<!DOCTYPE html>


  <html class="dark page-post">


<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="utf-8">
  
  <title>webpack回顾篇 | Poetry&#39;s Blog</title>

  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

  
    <meta name="keywords" content="优化,webpack,">
  

  <meta name="description" content="基于webpack3  一、webpack简介1.1 版本更迭 大版本变化  1.2 功能进化Webpack V1  编译、打包 HMR (模块热更新) 代码分割 文件处理  Webpack V2  Tree Shaking ES module 动态 Import 新的文档  Webpack V3  Scope Hoisting (作用域提升) Magic Comments （配合动态impor">
<meta name="keywords" content="优化,webpack">
<meta property="og:type" content="article">
<meta property="og:title" content="webpack回顾篇">
<meta property="og:url" content="http://blog.poetries.top/2018/11/21/webpack-review/index.html">
<meta property="og:site_name" content="Poetry&#39;s Blog">
<meta property="og:description" content="基于webpack3  一、webpack简介1.1 版本更迭 大版本变化  1.2 功能进化Webpack V1  编译、打包 HMR (模块热更新) 代码分割 文件处理  Webpack V2  Tree Shaking ES module 动态 Import 新的文档  Webpack V3  Scope Hoisting (作用域提升) Magic Comments （配合动态impor">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/644.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/645.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/646.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/647.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/648.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/649.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/650.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/651.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/652.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/653.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/654.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/655.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/656.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/657.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/658.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/659.png">
<meta property="og:image" content="https://poetries1.gitee.io/img-repo/2019/10/660.png">
<meta property="og:updated_time" content="2020-08-15T04:25:31.942Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="webpack回顾篇">
<meta name="twitter:description" content="基于webpack3  一、webpack简介1.1 版本更迭 大版本变化  1.2 功能进化Webpack V1  编译、打包 HMR (模块热更新) 代码分割 文件处理  Webpack V2  Tree Shaking ES module 动态 Import 新的文档  Webpack V3  Scope Hoisting (作用域提升) Magic Comments （配合动态impor">
<meta name="twitter:image" content="https://poetries1.gitee.io/img-repo/2019/10/644.png">

  

  
    <link rel="icon" href="/favicon.ico">
  

  <link href="/css/styles.css?v=c114cbeddx" rel="stylesheet">
<link href="/css/other.css?v=c114cbeddx" rel="stylesheet">


  
    <link rel="stylesheet" href="/css/personal-style.css">
  

  

  
  <script type="text/javascript">
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "//hm.baidu.com/hm.js?40b1f89aa80f2527b3db779c6898c879";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>


  
  <script type="text/javascript">
	(function(){
	    var bp = document.createElement('script');
	    var curProtocol = window.location.protocol.split(':')[0];
	    if (curProtocol === 'https') {
	        bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';        
	    }
	    else {
	        bp.src = 'http://push.zhanzhang.baidu.com/push.js';
	    }
	    var s = document.getElementsByTagName("script")[0];
	    s.parentNode.insertBefore(bp, s);
	})();
  </script>



  
    <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
    <link rel="stylesheet" href="//cdn.bootcss.com/font-awesome/4.3.0/css/font-awesome.min.css">
  

  <!-- 聊天系统 -->
  
    
   <link type="text/css" rel="stylesheet" href="/renxi/default.css">
   <style>
      #modal {
        position: static !important;
      }
      .filter {
        width: 100%;
        height: 100%;
        position: absolute;
        top: 0;
        left: 0;
        background: #fe5757;
        animation: colorChange 30s ease-in-out infinite;
        animation-fill-mode: both;
        mix-blend-mode: overlay;
      }
  
      @keyframes colorChange {
        0%, 100% {
            opacity: 0;
        }
        50% {
            opacity: .9;
        }
      }
   </style>
</head>
</html>
<body>
  
  
    <span id="toolbox-mobile" class="toolbox-mobile">导航</span>
  

  <div class="post-header CENTER">
   
  <div class="toolbox">
    <a class="toolbox-entry" href="/">
      <span class="toolbox-entry-text">导航</span>
      <i class="icon-angle-down"></i>
      <i class="icon-home"></i>
    </a>
    <ul class="list-toolbox">
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/archives/"
            rel="noopener noreferrer"
            target="_self"
            >
            博客
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/categories/"
            rel="noopener noreferrer"
            target="_self"
            >
            分类
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/tags/"
            rel="noopener noreferrer"
            target="_self"
            >
            标签
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/search/"
            rel="noopener noreferrer"
            target="_self"
            >
            搜索
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/link/"
            rel="noopener noreferrer"
            target="_self"
            >
            友链
          </a>
        </li>
      
        <li class="item-toolbox">
          <a
            class="CIRCLE"
            href="/about/"
            rel="noopener noreferrer"
            target="_self"
            >
            关于
          </a>
        </li>
      
    </ul>
  </div>


</div>


  <div id="toc" class="toc-article">
    <strong class="toc-title">文章目录<i class="iconfont toc-title" style="display:inline-block;color:#87998d;width:20px;height:20px;">&#xf004b;</i></strong>
    <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#一、webpack简介"><span class="toc-text">一、webpack简介</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-1-版本更迭"><span class="toc-text">1.1 版本更迭</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-2-功能进化"><span class="toc-text">1.2 功能进化</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#二、webpack核心概念"><span class="toc-text">二、webpack核心概念</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#2-1-Entry"><span class="toc-text">2.1 Entry</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-2-Output"><span class="toc-text">2.2 Output</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-3-Loaders"><span class="toc-text">2.3 Loaders</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#2-3-1-常用Loader"><span class="toc-text">2.3.1 常用Loader</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-4-Plugins"><span class="toc-text">2.4 Plugins</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#2-4-1-常用plugins"><span class="toc-text">2.4.1 常用plugins</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-5-名词"><span class="toc-text">2.5 名词</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#三、初探-webpack"><span class="toc-text">三、初探 webpack</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#3-1-使用babel打包es6"><span class="toc-text">3.1 使用babel打包es6</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#3-1-1-编译-ES-6-7"><span class="toc-text">3.1.1 编译 ES 6/7</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-2-打包-Typescript"><span class="toc-text">3.2 打包 Typescript</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-3-提取-js-的公用代码"><span class="toc-text">3.3 提取 js 的公用代码</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-4-代码分割和懒加载"><span class="toc-text">3.4 代码分割和懒加载</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-5-处理-CSS-和-CSS-模块化"><span class="toc-text">3.5 处理 CSS 和 CSS 模块化</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-6-PostCSS-in-Webpack"><span class="toc-text">3.6 PostCSS in Webpack</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-7-Tree-shaking"><span class="toc-text">3.7 Tree shaking</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#3-7-1-JS-Tree-shaking"><span class="toc-text">3.7.1 JS Tree shaking</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-7-2-CSS-Tree-shaking"><span class="toc-text">3.7.2 CSS Tree shaking</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#四、由浅入深Webpack"><span class="toc-text">四、由浅入深Webpack</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#4-1-文件处理"><span class="toc-text">4.1 文件处理</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#4-1-1-图片处理"><span class="toc-text">4.1.1 图片处理</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#4-1-2-处理雪碧图、base64、压缩图片"><span class="toc-text">4.1.2 处理雪碧图、base64、压缩图片</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#4-1-2-处理字体文件"><span class="toc-text">4.1.2 处理字体文件</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#4-1-3-处理第三方-JS-库"><span class="toc-text">4.1.3 处理第三方 JS 库</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-2-HTML-in-webpack-自动生成HTML"><span class="toc-text">4.2 HTML in webpack(自动生成HTML)</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#4-2-1-生成-HTML"><span class="toc-text">4.2.1 生成 HTML</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#4-2-2-HTML-中引入图片"><span class="toc-text">4.2.2 HTML 中引入图片</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#4-2-3-配合优化"><span class="toc-text">4.2.3 配合优化</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#五、Webpack-环境配置"><span class="toc-text">五、Webpack 环境配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#5-1-Webpack-Watch-Mode"><span class="toc-text">5.1 Webpack Watch Mode</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-2-Webpack-Dev-Server"><span class="toc-text">5.2 Webpack Dev Server</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#5-2-1-Dev-Server"><span class="toc-text">5.2.1 Dev Server</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#5-2-2-proxy代理远程接口"><span class="toc-text">5.2.2 proxy代理远程接口</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#5-2-3-模块热更新"><span class="toc-text">5.2.3 模块热更新</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#5-2-4-开启调试SourceMap"><span class="toc-text">5.2.4 开启调试SourceMap</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#5-2-5-设置-ESLint-检查代码格式"><span class="toc-text">5.2.5 设置 ESLint 检查代码格式</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#5-2-6-区分开发环境-和-生产环境"><span class="toc-text">5.2.6 区分开发环境 和 生产环境</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-3-使用-middleware-来搭建开发环境"><span class="toc-text">5.3 使用 middleware 来搭建开发环境</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#六、webpack实战场景"><span class="toc-text">六、webpack实战场景</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#6-1-分析打包结果"><span class="toc-text">6.1 分析打包结果</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-2-优化打包速度"><span class="toc-text">6.2 优化打包速度</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#6-2-1-方法一：分开vendor和app"><span class="toc-text">6.2.1 方法一：分开vendor和app</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#6-2-2-方法二：UglifyJsPlugin并行处理"><span class="toc-text">6.2.2 方法二：UglifyJsPlugin并行处理</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#6-2-3-方法三：happyPack"><span class="toc-text">6.2.3 方法三：happyPack</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#6-2-4-方法四：较少babel-loader编译时间"><span class="toc-text">6.2.4 方法四：较少babel-loader编译时间</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#6-2-5-其他"><span class="toc-text">6.2.5 其他</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-3-长缓存优化"><span class="toc-text">6.3 长缓存优化</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-4-多页面应用"><span class="toc-text">6.4 多页面应用</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#6-4-1-多页面特点"><span class="toc-text">6.4.1 多页面特点</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#6-4-2-多页面多配置"><span class="toc-text">6.4.2 多页面多配置</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#6-4-3-多页面单配置"><span class="toc-text">6.4.3 多页面单配置</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#七、更多学习"><span class="toc-text">七、更多学习</span></a></li></ol>
  </div>
  




<div class="content content-post CENTER">
   <!-- canvas 彩带 -->
<canvas id="evanyou" width="1302" height="678" style="position: fixed;width: 100%;height: 100%;top: 0;left:0;z-index:-1;"></canvas>

<article id="post-webpack-review" class="article article-type-post" itemprop="blogPost">
  <header class="article-header" style="position:relative;">
    <h1 class="post-title">webpack回顾篇</h1>

    <div class="article-meta">
      <span>
        <i class="icon-calendar"></i>
        <span>2018.11.21</span>
      </span>

      
        <span class="article-author">
          <i class="icon-user"></i>
          <span>Poetry</span>
        </span>
      

      
  <span class="article-category">
    <i class="icon-list"></i>
    <a class="article-category-link" href="/categories/Front-End/">Front-End</a>
  </span>



      

      
      <i class="fa fa-eye"></i> 
        <span id="busuanzi_container_page_pv">
           &nbsp热度 <span id="busuanzi_value_page_pv">
           <i class="fa fa-spinner fa-spin"></i></span>℃
        </span>
      
      
       
          <span class="post-count">
            <i class="fa fa-file-word-o"></i>&nbsp
            <span>字数统计 8.7k字</span>
          </span>

          <span class="post-count">
            <i class="fa fa-columns"></i>&nbsp
            <span>阅读时长 43分</span>
          </span>
      
      
    </div>

    <i class="iconfont" id="toc-eye" style="display:inline-block;color:#b36619;position:absolute;top:0;right:0;cursor:pointer;
    font-size: 24px;">&#xe61c;</i>

  </header>

  <div class="article-content">
    
      <div id="container">
        <blockquote>
<p>基于<code>webpack3</code></p>
</blockquote>
<h2 id="一、webpack简介"><a href="#一、webpack简介" class="headerlink" title="一、webpack简介"></a>一、webpack简介</h2><h3 id="1-1-版本更迭"><a href="#1-1-版本更迭" class="headerlink" title="1.1 版本更迭"></a>1.1 版本更迭</h3><p><img src="https://poetries1.gitee.io/img-repo/2019/10/644.png" alt></p>
<p><strong>大版本变化</strong></p>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/645.png" alt></p>
<h3 id="1-2-功能进化"><a href="#1-2-功能进化" class="headerlink" title="1.2 功能进化"></a>1.2 功能进化</h3><p><strong>Webpack V1</strong></p>
<ul>
<li>编译、打包</li>
<li><code>HMR</code> (模块热更新)</li>
<li>代码分割</li>
<li>文件处理</li>
</ul>
<p><strong>Webpack V2</strong></p>
<ul>
<li><code>Tree Shaking</code></li>
<li><code>ES module</code></li>
<li>动态 <code>Import</code></li>
<li>新的文档</li>
</ul>
<p><strong>Webpack V3</strong></p>
<ul>
<li><code>Scope Hoisting</code> (作用域提升)</li>
<li><code>Magic Comments</code> （配合动态<code>import</code>使用）</li>
</ul>
<blockquote>
<p>版本迁移</p>
</blockquote>
<p><strong>V1 -&gt; V2</strong></p>
<p>迁移指南 <a href="https://doc.webpack-china.org/guides/migrating/" target="_blank" rel="noopener">https://doc.webpack-china.org/guides/migrating/</a></p>
<p><strong>V2 -&gt; V3</strong></p>
<p>更新升级即可</p>
<h2 id="二、webpack核心概念"><a href="#二、webpack核心概念" class="headerlink" title="二、webpack核心概念"></a>二、webpack核心概念</h2><h3 id="2-1-Entry"><a href="#2-1-Entry" class="headerlink" title="2.1 Entry"></a>2.1 Entry</h3><ul>
<li>代码的入口</li>
<li>打包的入口</li>
<li>单个或多个</li>
</ul>
<blockquote>
<p>写法建议使用键值对写法</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  entry: <span class="string">'index.js'</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  entry: <span class="string">'[index.js'</span>,<span class="string">'vendor.js'</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  entry: &#123;</span><br><span class="line">      index:<span class="string">'index.js'</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  entry: &#123;</span><br><span class="line">      index:[<span class="string">'index.js'</span>,<span class="string">'app.js'</span>],</span><br><span class="line">      vendor: <span class="string">'vendor.js'</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="2-2-Output"><a href="#2-2-Output" class="headerlink" title="2.2 Output"></a>2.2 Output</h3><ul>
<li>打包成的文件(<code>bundle</code>)</li>
<li>一个或多个</li>
<li>自定义规则</li>
<li>配合<code>CDN</code></li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  entry: <span class="string">'index.js'</span>,</span><br><span class="line">  output: &#123;</span><br><span class="line">      filename: <span class="string">'index.min.js'</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  entry: &#123;</span><br><span class="line">    index: <span class="string">'index.js'</span>,</span><br><span class="line">    vendor: <span class="string">'vendor.js'</span></span><br><span class="line">  &#125;,</span><br><span class="line">  output: &#123;</span><br><span class="line">      filename: <span class="string">'[name].min[hash:5].js'</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="2-3-Loaders"><a href="#2-3-Loaders" class="headerlink" title="2.3 Loaders"></a>2.3 Loaders</h3><ul>
<li>处理文件</li>
<li>转化为模块</li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  <span class="built_in">module</span>: &#123;</span><br><span class="line">      rules: [</span><br><span class="line">        &#123;</span><br><span class="line">            test: <span class="regexp">/\.css$/</span>,</span><br><span class="line">            use: <span class="string">'css-loader'</span></span><br><span class="line">        &#125;</span><br><span class="line">      ]</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="2-3-1-常用Loader"><a href="#2-3-1-常用Loader" class="headerlink" title="2.3.1 常用Loader"></a>2.3.1 常用Loader</h4><p><strong>编译相关</strong></p>
<ul>
<li><code>babel-loader</code></li>
<li><code>ts-loader</code></li>
</ul>
<p><strong>样式相关</strong></p>
<ul>
<li><code>style-loader</code></li>
<li><code>css-loader</code></li>
<li><code>less-loader</code></li>
<li><code>postcss-loader</code></li>
</ul>
<p><strong>文件相关</strong></p>
<ul>
<li><code>file-loader</code></li>
<li><code>url-loader</code></li>
</ul>
<h3 id="2-4-Plugins"><a href="#2-4-Plugins" class="headerlink" title="2.4 Plugins"></a>2.4 Plugins</h3><ul>
<li>参与打包整个过程</li>
<li>打包优化和压缩</li>
<li>配置编译时的变量</li>
<li>极其灵活</li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line"> plugins: [</span><br><span class="line">    <span class="keyword">new</span> webpack.optimize.UglifyJsPlugin()</span><br><span class="line"> ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="2-4-1-常用plugins"><a href="#2-4-1-常用plugins" class="headerlink" title="2.4.1 常用plugins"></a>2.4.1 常用plugins</h4><p><strong>优化相关</strong></p>
<ul>
<li><code>CommonsChunkPlugin</code></li>
<li><code>UglifyJsWebpackPlugin</code></li>
</ul>
<p><strong>功能相关</strong></p>
<ul>
<li><code>ExtractTextWebpackPlugin</code> 提取css</li>
<li><code>HtmlWebpackPlugin</code> 生成HTML模板</li>
<li><code>HotModuleReplacementPlugin</code> 热模块替换</li>
<li><code>CopyWebpackPlugin</code> 拷贝文件</li>
</ul>
<h3 id="2-5-名词"><a href="#2-5-名词" class="headerlink" title="2.5 名词"></a>2.5 名词</h3><ul>
<li><code>Chunk</code> 打包过程分割的代码块</li>
<li><code>Bundle</code> 打包后的文件</li>
<li><code>Module</code> </li>
</ul>
<h2 id="三、初探-webpack"><a href="#三、初探-webpack" class="headerlink" title="三、初探 webpack"></a>三、初探 webpack</h2><h3 id="3-1-使用babel打包es6"><a href="#3-1-使用babel打包es6" class="headerlink" title="3.1 使用babel打包es6"></a>3.1 使用babel打包es6</h3><h4 id="3-1-1-编译-ES-6-7"><a href="#3-1-1-编译-ES-6-7" class="headerlink" title="3.1.1 编译 ES 6/7"></a>3.1.1 编译 ES 6/7</h4><p><strong>Babel</strong></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install babel-loader@8.0.0-beta.0 @babel/core</span><br><span class="line">npm install –save-dev babel-loader babel-core</span><br></pre></td></tr></table></figure>
<p><strong>Babel Presets</strong></p>
<blockquote>
<p>主要有几种类型选择</p>
</blockquote>
<ul>
<li><code>es2015</code></li>
<li><code>es2016</code></li>
<li><code>es2017</code></li>
<li><code>env</code></li>
<li><code>babel-preset-react</code></li>
<li><code>babel-preset-stage 0 - 3</code></li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install @babel/preset-env –save-dev</span><br><span class="line">npm install babel-preset-env –save-dev</span><br></pre></td></tr></table></figure>
<p><strong>Babel Polyfill</strong></p>
<blockquote>
<p>针对一些不能处理的函数方法(<code>Generator</code>、<code>Set</code>、<code>Map</code>、<code>Array.from...</code>)需要用到<code>babel-Polyfill</code>处理</p>
</blockquote>
<ul>
<li>全局垫片</li>
<li>为应用准备</li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install babel-polyfill –save</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">import “babel-polyfill”</span><br></pre></td></tr></table></figure>
<p><strong>Babel Runtime Transform</strong></p>
<ul>
<li>局部垫片</li>
<li>为开发框架准备</li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install babel-plugin-transform-runtime –save-dev</span><br><span class="line"></span><br><span class="line">npm install babel-runtime –save</span><br></pre></td></tr></table></figure>
<p>例子</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">       app: <span class="string">'app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        filename: <span class="string">'[name].[hash:8].js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">        rules:[</span><br><span class="line">            test: <span class="regexp">/\.js$/</span>,</span><br><span class="line">            use: &#123;</span><br><span class="line">                loader: <span class="string">'babel-loader'</span>,</span><br><span class="line">                options: &#123;</span><br><span class="line">                    presets: [</span><br><span class="line">                        <span class="string">'@babel/preset-env'</span>,&#123;</span><br><span class="line">                            <span class="comment">//指定target为根据哪些语法编译</span></span><br><span class="line">                            targets: &#123;</span><br><span class="line">                                browsers: [<span class="string">'&gt; 1%'</span>,<span class="string">'last 2 versions'</span>]</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                    ]</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            exclude: <span class="string">'/node_modules'</span></span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>对于<code>webpack</code>中<code>babel</code>的配置可以单独提取处理<code>.babelrc</code>统一管理</p>
</blockquote>
<figure class="highlight"><table><tr><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    <span class="attr">"presets"</span>: [</span><br><span class="line">        [<span class="string">"@babel/preset-env"</span>,&#123;</span><br><span class="line">            targets: &#123;</span><br><span class="line">                browsers: ['&gt; 1%','last 2 versions']</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;]</span><br><span class="line">    ],</span><br><span class="line">    "plugins": [</span><br><span class="line">      <span class="string">"transform-runtime"</span></span><br><span class="line">    ]</span><br><span class="line">]</span><br></pre></td></tr></table></figure>
<h3 id="3-2-打包-Typescript"><a href="#3-2-打包-Typescript" class="headerlink" title="3.2 打包 Typescript"></a>3.2 打包 Typescript</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm i typescipt ts-loader  --save-dev</span><br><span class="line">npm i typescipt awesome-typescript-loader  --save-dev</span><br></pre></td></tr></table></figure>
<p>配置</p>
<ul>
<li><code>tsconfig.json</code></li>
<li><code>webpack.config.js</code></li>
</ul>
<p><strong>tsconfig</strong></p>
<ul>
<li>配置选项:官网<code>/docs/handbook/compiler-options.html</code></li>
<li>常用选项 <code>compilerOptions</code> <code>include</code> <code>exclude</code></li>
</ul>
<p><strong>声明文件</strong></p>
<blockquote>
<p>用于编译时检查错误</p>
</blockquote>
<p>以<code>loadsh</code>为例，需要安装<code>@types/lodash</code>带有声明文件的，而不是安装<code>lodash</code></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install @types/lodash</span><br><span class="line">npm install @types/vue</span><br></pre></td></tr></table></figure>
<p><strong>Typings</strong></p>
<blockquote>
<p>也可以这样安装带有<code>type</code>的包</p>
</blockquote>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install typings</span><br><span class="line">typings install lodash</span><br></pre></td></tr></table></figure>
<p>例子</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        <span class="string">'app'</span>: <span class="string">'app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        filename: <span class="string">'[name].bundle.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">        rules: [</span><br><span class="line">            test: <span class="regexp">/\.tsx?$/</span>,</span><br><span class="line">            use: &#123;</span><br><span class="line">                loader: <span class="string">'ts-loader'</span></span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>在项目根目录创建<code>tsconfig.json</code></p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">&#123;</span><br><span class="line">   <span class="string">"compilerOptions"</span>: &#123;</span><br><span class="line">        <span class="string">"module"</span>: <span class="string">"comonjs"</span>,</span><br><span class="line">        <span class="string">"target"</span>: <span class="string">"es5"</span>, <span class="comment">//编译后的文件在哪个环境运行</span></span><br><span class="line">        <span class="string">"allowJs"</span>: <span class="literal">true</span>,<span class="comment">//允许js语法</span></span><br><span class="line">   &#125;,</span><br><span class="line">   <span class="string">"include"</span>: [</span><br><span class="line">       <span class="comment">//编译路径</span></span><br><span class="line">       <span class="string">"./src/*"</span></span><br><span class="line">   ],</span><br><span class="line">   <span class="string">"exclude"</span>: [</span><br><span class="line">       <span class="comment">//排除编译文件</span></span><br><span class="line">       <span class="string">"./node_modules"</span></span><br><span class="line">   ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="3-3-提取-js-的公用代码"><a href="#3-3-提取-js-的公用代码" class="headerlink" title="3.3 提取 js 的公用代码"></a>3.3 提取 js 的公用代码</h3><ul>
<li>减少代码冗余</li>
<li>提高加载速度</li>
</ul>
<blockquote>
<p>主要使用内置插件实现<code>webpack.optimize.CommonsChunkPlugin</code></p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">&#123;</span><br><span class="line">	plugins: [</span><br><span class="line">	     <span class="keyword">new</span> webpack.optimize.CommonsChunkPlugin(option)</span><br><span class="line">	]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>例子</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        <span class="string">"pageA"</span>: <span class="string">"./src/pageA"</span>,</span><br><span class="line">        <span class="string">"pageB"</span>: <span class="string">"./src/pageB"</span>,</span><br><span class="line">        <span class="string">"vendor"</span>: [<span class="string">'loash'</span>]<span class="comment">//业务代码和第三方代码区分开,给loash单独打一个包</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'./dist'</span>),</span><br><span class="line">        filename: <span class="string">'[name].bundle.js'</span>,</span><br><span class="line">        chunkFilename: <span class="string">'[name].chunk.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    plugins: [</span><br><span class="line">    <span class="comment">// 提取common</span></span><br><span class="line">    <span class="keyword">new</span> webpack.optimize.CommonsChunkPlugin(&#123;</span><br><span class="line">         name: <span class="string">'common'</span>,</span><br><span class="line">         minChunks:<span class="number">2</span>,<span class="comment">//出现两次就打包成common代码</span></span><br><span class="line">         chunks: [<span class="string">'pageA'</span>,<span class="string">'pageB'</span>]<span class="comment">//指定范围提取公共代码</span></span><br><span class="line">     &#125;)</span><br><span class="line">        </span><br><span class="line">    <span class="comment">// 提取vendor、取业务代码manifest</span></span><br><span class="line">     <span class="keyword">new</span> webpack.optimize.CommonsChunkPlugin(&#123;</span><br><span class="line">         <span class="comment">//把entry的vendor代码和这里的common（webpack打包的）代码合并</span></span><br><span class="line">         names: [<span class="string">'vendor'</span>,<span class="string">'manifest'</span>]</span><br><span class="line">         minChunks: <span class="literal">Infinity</span></span><br><span class="line">     &#125;)</span><br><span class="line">     <span class="comment">// ==== 提取业务代码manifest== 合并到上面names中</span></span><br><span class="line">     <span class="comment">// 如果不想把webpack打包的代码和vendor代码合并 需要提取到manifest</span></span><br><span class="line">     <span class="comment">//new webpack.optimize.CommonsChunkPlugin(&#123;</span></span><br><span class="line">         <span class="comment">// webpack代码和vendordiam区分开</span></span><br><span class="line">       <span class="comment">//  name: 'manifest' //manifest即生成</span></span><br><span class="line">       <span class="comment">//  minChunks: Infinity</span></span><br><span class="line">    <span class="comment">// &#125;)</span></span><br><span class="line">     </span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/646.png" alt></p>
<h3 id="3-4-代码分割和懒加载"><a href="#3-4-代码分割和懒加载" class="headerlink" title="3.4 代码分割和懒加载"></a>3.4 代码分割和懒加载</h3><p><strong>第一种方式：通过wepack内置方法</strong></p>
<blockquote>
<p><code>require.ensure</code>动态加载一个模块，接收四个参数</p>
</blockquote>
<ul>
<li><code>[]:dependencies</code> 初次并不会执行</li>
<li><code>callback</code>的时候才会执行</li>
<li><code>errorCallback</code> 可省略</li>
<li><code>chunkName</code></li>
</ul>
<p><strong>第二种方式：通过ES2015 Loader Spec</strong></p>
<blockquote>
<p><code>System.import()</code>后面演变为<code>import()</code>来动态加载模块</p>
</blockquote>
<p><code>import()</code>方式返回一个<code>promise</code>在<code>import</code>中传入需要依赖的明，动态加载模块，就可以像使用<code>Promise</code>一样使用<code>import().then()</code></p>
<p><strong>代码分割场景</strong></p>
<ul>
<li>分离业务代码 和 第三方依赖</li>
<li>分离业务代码 和 业务公共代码 和 第三方依赖</li>
<li>分离首次加载 和 访问后加载的代码</li>
</ul>
<p>例子</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        <span class="string">"pageA"</span>: <span class="string">"./src/pageA"</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'./dist'</span>),</span><br><span class="line">        publicPath: <span class="string">'./dist/'</span>,<span class="comment">//动态加载路径</span></span><br><span class="line">        filename: <span class="string">'[name].bundle.js'</span>,</span><br><span class="line">        chunkFilename: <span class="string">'[name].chunk.js'</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>目标是提取<code>pageA</code>、<code>pageB</code>中公共的模块<code>moduleA</code></p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//src/pageA.js</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="string">'./subPageA'</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">'./subPageB'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//ensure的时候代码不会执行 需要在下面加载一次</span></span><br><span class="line"><span class="built_in">require</span>.ensure([<span class="string">'lodash'</span>],<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> _ = <span class="built_in">require</span>(<span class="string">'lodash'</span>)</span><br><span class="line">    _.join([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line">&#125;,<span class="string">'vendor'</span>)<span class="comment">// 指定chunk名称</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="string">'pageA'</span></span><br></pre></td></tr></table></figure>
<p>运行打包这时<code>loadash</code>提取到<code>vendor</code>中</p>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/647.png" alt></p>
<p>这时候还不是我们想要的</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//src/pageA.js</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">require</span>.include(<span class="string">'./moduleA'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(page === <span class="string">'subPageA'</span>)&#123;</span><br><span class="line">  <span class="built_in">require</span>.ensure([<span class="string">'./subPageA'</span>],<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> subPageA = <span class="built_in">require</span>(<span class="string">'./subPageA'</span>)</span><br><span class="line">    &#125;,<span class="string">'subPageA'</span>)<span class="comment">// 指定chunk名称</span></span><br><span class="line">&#125;<span class="keyword">else</span>&#123;</span><br><span class="line">  <span class="built_in">require</span>.ensure([<span class="string">'./subPageB'</span>],<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> subPageB = <span class="built_in">require</span>(<span class="string">'./subPageB'</span>)</span><br><span class="line">    &#125;,<span class="string">'subPageB'</span>)<span class="comment">// 指定chunk名称</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//ensure的时候代码不会执行 需要在下面加载一次</span></span><br><span class="line"><span class="built_in">require</span>.ensure([<span class="string">'lodash'</span>],<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> _ = <span class="built_in">require</span>(<span class="string">'lodash'</span>)</span><br><span class="line">    _.join([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line">&#125;,<span class="string">'vendor'</span>)<span class="comment">// 指定chunk名称</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="string">'pageA'</span></span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/648.png" alt></p>
<blockquote>
<p>这时候这有<code>pageA</code>中才有<code>moduleA</code></p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/649.png" alt></p>
<blockquote>
<p>新建一个html验证是否动态加载</p>
</blockquote>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"./dist/pageA.bundle.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/650.png" alt></p>
<p><strong>import()动态加载的写法</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//src/pageA.js</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">require</span>.include(<span class="string">'./moduleA'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> page = <span class="string">'subPageA'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(page === <span class="string">'subPageA'</span>)&#123;</span><br><span class="line"> <span class="comment">// 指定chunkName /** webpackChunkName: 'subPageA' **/ </span></span><br><span class="line">  <span class="keyword">import</span>(<span class="comment">/** webpackChunkName: 'subPageA' **/</span>,<span class="string">'./subPageA'</span>).then(<span class="function"><span class="keyword">function</span>(<span class="params">subPageA</span>)</span>&#123;</span><br><span class="line">      <span class="built_in">console</span>.log(subPageA)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;<span class="keyword">else</span>&#123;</span><br><span class="line">  <span class="keyword">import</span>(<span class="comment">/** webpackChunkName: 'subPageB' **/</span><span class="string">'./subPageB'</span>).then(<span class="function"><span class="keyword">function</span>(<span class="params">subPageB</span>)</span>&#123;</span><br><span class="line">      <span class="built_in">console</span>.log(subPageB)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 异步加载lodash</span></span><br><span class="line"><span class="comment">//ensure的时候代码不会执行 需要在下面加载一次</span></span><br><span class="line"><span class="built_in">require</span>.ensure([<span class="string">'lodash'</span>],<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> _ = <span class="built_in">require</span>(<span class="string">'lodash'</span>)</span><br><span class="line">    _.join([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line">&#125;,<span class="string">'vendor'</span>)<span class="comment">// 指定chunk名称</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="string">'pageA'</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>如果<code>/** webpackChunkName: &#39;subPageA&#39; **/</code>相同，则会合并处理</p>
</blockquote>
<p>合并了<code>subPageA</code>和<code>subPageB</code></p>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/651.png" alt></p>
<p>来看看打包后的文件，既有A、B</p>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/652.png" alt></p>
<p><strong>在<code>webpack</code>代码分割中使用<code>async</code>异步加载</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        <span class="string">"pageA"</span>: <span class="string">"./src/pageA"</span>,</span><br><span class="line">        <span class="string">"pageB"</span>: <span class="string">"./src/pageB"</span>,</span><br><span class="line">        <span class="string">"vendor"</span>: [<span class="string">'loash'</span>]<span class="comment">//业务代码和第三方代码区分开,给loash单独打一个包</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'./dist'</span>),</span><br><span class="line">        filename: <span class="string">'[name].bundle.js'</span>,</span><br><span class="line">        chunkFilename: <span class="string">'[name].chunk.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    plugins: [</span><br><span class="line">    <span class="comment">// add 异步模块</span></span><br><span class="line">    <span class="keyword">new</span> webpack.optimize.CommonsChunkPlugin(&#123;</span><br><span class="line">        aysnc:<span class="string">'async-common'</span>,<span class="comment">//异步共同的东西</span></span><br><span class="line">        children: <span class="literal">true</span>,</span><br><span class="line">        names: [<span class="string">'vendor'</span>,<span class="string">'manifest'</span>]</span><br><span class="line">        minChunks: <span class="literal">Infinity</span></span><br><span class="line">    &#125;)</span><br><span class="line">     </span><br><span class="line">     </span><br><span class="line">    <span class="comment">// 提取vendor、取业务代码manifest</span></span><br><span class="line">     <span class="keyword">new</span> webpack.optimize.CommonsChunkPlugin(&#123;</span><br><span class="line">         <span class="comment">//把entry的vendor代码和这里的common（webpack打包的）代码合并</span></span><br><span class="line">         names: [<span class="string">'vendor'</span>,<span class="string">'manifest'</span>]</span><br><span class="line">         minChunks: <span class="literal">Infinity</span></span><br><span class="line">     &#125;)</span><br><span class="line">     </span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//src/subPageA.js</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="string">'./moduleA'</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'this. is subPageA'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="string">'subPageA'</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//src/subPageB.js</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="string">'./moduleA'</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'this. is subPageB'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="string">'subPageB'</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//src/subPageB.js</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="string">'./moduleA'</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'this. is moduleA'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="string">'moduleA'</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//src/pageA.js</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 异步加载不能include 否则会和pageA打包到一起</span></span><br><span class="line"><span class="comment">// require.include('./moduleA')</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> _ <span class="keyword">from</span> <span class="string">'lodash'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> page = <span class="string">'subPageA'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(page === <span class="string">'subPageA'</span>)&#123;</span><br><span class="line"> <span class="comment">// 指定chunkName /** webpackChunkName: 'subPageA' **/ </span></span><br><span class="line">  <span class="keyword">import</span>(<span class="comment">/** webpackChunkName: 'subPageA' **/</span>,<span class="string">'./subPageA'</span>).then(<span class="function"><span class="keyword">function</span>(<span class="params">subPageA</span>)</span>&#123;</span><br><span class="line">      <span class="built_in">console</span>.log(subPageA)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;<span class="keyword">else</span>&#123;</span><br><span class="line">  <span class="keyword">import</span>(<span class="comment">/** webpackChunkName: 'subPageB' **/</span><span class="string">'./subPageB'</span>).then(<span class="function"><span class="keyword">function</span>(<span class="params">subPageB</span>)</span>&#123;</span><br><span class="line">      <span class="built_in">console</span>.log(subPageB)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// === lodash不在异步加载</span></span><br><span class="line"><span class="comment">//ensure的时候代码不会执行 需要在下面加载一次</span></span><br><span class="line"><span class="comment">//require.ensure(['lodash'],function()&#123;</span></span><br><span class="line"><span class="comment">//    var _ = require('lodash')</span></span><br><span class="line"><span class="comment">//    _.join([1,2,3])</span></span><br><span class="line"><span class="comment">//&#125;,'vendor')// 指定chunk名称</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="string">'pageA'</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//src/pageB.js</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> _ <span class="keyword">from</span> <span class="string">'lodash'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> page = <span class="string">'subPageB'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(page === <span class="string">'subPageA'</span>)&#123;</span><br><span class="line"> <span class="comment">// 指定chunkName /** webpackChunkName: 'subPageA' **/ </span></span><br><span class="line">  <span class="keyword">import</span>(<span class="comment">/** webpackChunkName: 'subPageA' **/</span>,<span class="string">'./subPageA'</span>).then(<span class="function"><span class="keyword">function</span>(<span class="params">subPageA</span>)</span>&#123;</span><br><span class="line">      <span class="built_in">console</span>.log(subPageA)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;<span class="keyword">else</span>&#123;</span><br><span class="line">  <span class="keyword">import</span>(<span class="comment">/** webpackChunkName: 'subPageB' **/</span><span class="string">'./subPageB'</span>).then(<span class="function"><span class="keyword">function</span>(<span class="params">subPageB</span>)</span>&#123;</span><br><span class="line">      <span class="built_in">console</span>.log(subPageB)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// === lodash不在异步加载</span></span><br><span class="line"><span class="comment">//ensure的时候代码不会执行 需要在下面加载一次</span></span><br><span class="line"><span class="comment">//require.ensure(['lodash'],function()&#123;</span></span><br><span class="line"><span class="comment">//    var _ = require('lodash')</span></span><br><span class="line"><span class="comment">//    _.join([1,2,3])</span></span><br><span class="line"><span class="comment">//&#125;,'vendor')// 指定chunk名称</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="string">'pageB'</span></span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/653.png" alt><br><img src="https://poetries1.gitee.io/img-repo/2019/10/654.png" alt></p>
<blockquote>
<p>这样就把<code>subpageA</code>和<code>subPageB</code>共同依赖的<code>moduleA</code>异步提取出来</p>
</blockquote>
<h3 id="3-5-处理-CSS-和-CSS-模块化"><a href="#3-5-处理-CSS-和-CSS-模块化" class="headerlink" title="3.5 处理 CSS 和 CSS 模块化"></a>3.5 处理 CSS 和 CSS 模块化</h3><p><strong>引入css</strong></p>
<blockquote>
<p>需要两个<code>loader</code>，<code>style-loader</code>(创建标签到文档流中)、<code>css-loader</code>(可以<code>import</code>一个样式文件，使得在<code>js</code>中可以使用)</p>
</blockquote>
<p><strong>Style-Loader</strong></p>
<blockquote>
<p><code>style-loader</code>除了本身，还有这几个<code>loader</code></p>
</blockquote>
<ul>
<li><code>style-loader/url</code> 可以注入link标签到页面</li>
<li><code>style-loader/useable</code> 控制样式是否插入到页面中</li>
</ul>
<p>Style-Loader的options</p>
<ul>
<li><code>insertAt</code> （插入位置）</li>
<li><code>insertInto</code> （插入到<code>dom</code>）</li>
<li><code>singleton</code> （是否只使用一个<code>style</code> 标签）</li>
<li><code>transform</code> （转化，浏览器环境下，插入页面前）</li>
</ul>
<p>例子</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        publicPath: <span class="string">'./dist/'</span>, <span class="comment">//指定从项目中哪里引入资源 </span></span><br><span class="line">        filename: <span class="string">'[name].bundle.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">        <span class="comment">// loader解析从后往前处理</span></span><br><span class="line">        rules: [</span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.css$/</span>,</span><br><span class="line">                use: [</span><br><span class="line">                    &#123;</span><br><span class="line">                        <span class="comment">//loader: 'style-loader',</span></span><br><span class="line">                        loader: <span class="string">'style-loader/url'</span>, <span class="comment">//使用这个可以往页面注入link标签 而不是style,这个并不常用</span></span><br><span class="line">                    &#125;,</span><br><span class="line">                    &#123;</span><br><span class="line">                        <span class="comment">//loader: 'css-loader',</span></span><br><span class="line">                        loader: <span class="string">'file-loader'</span><span class="comment">//使用这个可以往页面注入link标签 而不是style 这个并不常用</span></span><br><span class="line">                    &#125;</span><br><span class="line">                ]</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>CSS-Loader</strong></p>
<p>options</p>
<ul>
<li><code>alias</code> （解析的别名）</li>
<li><code>importLoader</code> （<code>@import</code> ）</li>
<li><code>Minimize</code> （是否压缩）</li>
<li><code>modules</code> （启用<code>css-modules</code>）</li>
</ul>
<p><strong>CSS-Modules</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">localIdentName: &apos;[path][name]__[local]--[hash:base64:5]&apos;</span><br></pre></td></tr></table></figure>
<p>例子</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        publicPath: <span class="string">'./dist/'</span>, <span class="comment">//指定从项目中哪里引入资源 </span></span><br><span class="line">        filename: <span class="string">'[name].bundle.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">        <span class="comment">// loader解析从后往前处理</span></span><br><span class="line">        rules: [</span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.css$/</span>,</span><br><span class="line">                use: [</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'style-loader'</span>,</span><br><span class="line">                        options: &#123; </span><br><span class="line">                           <span class="comment">//合并多个style为一个</span></span><br><span class="line">                            singleton:<span class="literal">true</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'css-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                           minimize:<span class="literal">true</span>,</span><br><span class="line">                           modules: <span class="literal">true</span>,</span><br><span class="line">                           <span class="comment">// css模块化</span></span><br><span class="line">                           localIdentName: <span class="string">'[path][name]_[local]_[hash:base64:5]'</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                ]</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>配置Less / Sass</strong></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install less-loader less  --save-dev</span><br><span class="line">npm install sass-loader node-sass --save-dev</span><br></pre></td></tr></table></figure>
<p>例子</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        publicPath: <span class="string">'./dist/'</span>, <span class="comment">//指定从项目中哪里引入资源 </span></span><br><span class="line">        filename: <span class="string">'[name].bundle.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">        <span class="comment">// loader解析从后往前处理</span></span><br><span class="line">        rules: [</span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.(css|less)$/</span>,</span><br><span class="line">                use: [</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'style-loader'</span>,</span><br><span class="line">                        options: &#123; </span><br><span class="line">                           <span class="comment">//合并多个style为一个</span></span><br><span class="line">                            singleton:<span class="literal">true</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'css-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                           minimize:<span class="literal">true</span>,</span><br><span class="line">                           modules: <span class="literal">true</span>,</span><br><span class="line">                           <span class="comment">// css模块化</span></span><br><span class="line">                           localIdentName: <span class="string">'[path][name]_[local]_[hash:base64:5]'</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'less-loader'</span></span><br><span class="line">                    &#125;,</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'sass-loader'</span></span><br><span class="line">                    &#125;</span><br><span class="line">                ]</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>提取 CSS</strong></p>
<ul>
<li><code>extract-loader</code></li>
<li><code>ExtractTextWebpackPlugin</code></li>
</ul>
<p>例子</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        publicPath: <span class="string">'./dist/'</span>, <span class="comment">//指定从项目中哪里引入资源 </span></span><br><span class="line">        filename: <span class="string">'[name].bundle.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">        <span class="comment">// loader解析从后往前处理</span></span><br><span class="line">        rules: [</span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.(css|less)$/</span>,</span><br><span class="line">                use:</span><br><span class="line">                ExtractTextWebpackPlugin.extra(&#123;</span><br><span class="line">                    <span class="comment">// 提取css并不会自动加入到文档中，需要在HTML手动加入css文件</span></span><br><span class="line">                    fallback: &#123;</span><br><span class="line">                        loader: <span class="string">'style-loader'</span>,</span><br><span class="line">                        options: &#123; </span><br><span class="line">                           <span class="comment">//合并多个style为一个</span></span><br><span class="line">                            singleton:<span class="literal">true</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    <span class="comment">// 处理css</span></span><br><span class="line">                    use: [</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'css-loader'</span>,</span><br><span class="line">                            options: &#123;</span><br><span class="line">                               minimize:<span class="literal">true</span>,</span><br><span class="line">                               modules: <span class="literal">true</span>,</span><br><span class="line">                               <span class="comment">// css模块化</span></span><br><span class="line">                               localIdentName: <span class="string">'[path][name]_[local]_[hash:base64:5]'</span></span><br><span class="line">                        &#125;</span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'less-loader'</span></span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'sass-loader'</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    ]</span><br><span class="line">                &#125;)</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">    plugins: [</span><br><span class="line">        <span class="keyword">new</span> ExtractTextWebpackPlugin(&#123;</span><br><span class="line">            filename: <span class="string">'[name].min.css'</span>,</span><br><span class="line">            allChunks: <span class="literal">false</span> <span class="comment">//指定提取css范围，true所有import进来的css</span></span><br><span class="line">        &#125;)</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/655.png" alt></p>
<h3 id="3-6-PostCSS-in-Webpack"><a href="#3-6-PostCSS-in-Webpack" class="headerlink" title="3.6 PostCSS in Webpack"></a>3.6 PostCSS in Webpack</h3><p>安装</p>
<ul>
<li><code>postcss</code></li>
<li><code>postcss-loader</code></li>
<li><code>Autoprefixer</code></li>
<li><code>cssnano</code></li>
<li><code>postcss-cssnext</code></li>
</ul>
<p>例子</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        publicPath: <span class="string">'./dist/'</span>, <span class="comment">//指定从项目中哪里引入资源 </span></span><br><span class="line">        filename: <span class="string">'[name].bundle.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">        <span class="comment">// loader解析从后往前处理</span></span><br><span class="line">        rules: [</span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.(css|less)$/</span>,</span><br><span class="line">                use:</span><br><span class="line">                ExtractTextWebpackPlugin.extra(&#123;</span><br><span class="line">                    <span class="comment">// 提取css并不会自动加入到文档中，需要在HTML手动加入css文件</span></span><br><span class="line">                    fallback: &#123;</span><br><span class="line">                        loader: <span class="string">'style-loader'</span>,</span><br><span class="line">                        options: &#123; </span><br><span class="line">                           <span class="comment">//合并多个style为一个</span></span><br><span class="line">                            singleton:<span class="literal">true</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    <span class="comment">// 处理css</span></span><br><span class="line">                    use: [</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'css-loader'</span>,</span><br><span class="line">                            options: &#123;</span><br><span class="line">                               minimize:<span class="literal">true</span>,</span><br><span class="line">                               modules: <span class="literal">true</span>,</span><br><span class="line">                               <span class="comment">// css模块化</span></span><br><span class="line">                               localIdentName: <span class="string">'[path][name]_[local]_[hash:base64:5]'</span></span><br><span class="line">                        &#125;</span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'less-loader'</span></span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'sass-loader'</span></span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'postcss-loader'</span>,</span><br><span class="line">                            options: &#123;</span><br><span class="line">                                ident: <span class="string">'postcss'</span>,</span><br><span class="line">                                plugins: [</span><br><span class="line">                                    <span class="built_in">require</span>(<span class="string">'antoprefixer'</span>)()</span><br><span class="line">                                ]</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                    ]</span><br><span class="line">                &#125;)</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">    plugins: [</span><br><span class="line">        <span class="keyword">new</span> ExtractTextWebpackPlugin(&#123;</span><br><span class="line">            filename: <span class="string">'[name].min.css'</span>,</span><br><span class="line">            allChunks: <span class="literal">false</span> <span class="comment">//指定提取css范围，true所有import进来的css</span></span><br><span class="line">        &#125;)</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="3-7-Tree-shaking"><a href="#3-7-Tree-shaking" class="headerlink" title="3.7 Tree shaking"></a>3.7 Tree shaking</h3><h4 id="3-7-1-JS-Tree-shaking"><a href="#3-7-1-JS-Tree-shaking" class="headerlink" title="3.7.1 JS Tree shaking"></a>3.7.1 JS Tree shaking</h4><p><strong>使用场景</strong></p>
<ul>
<li>常规优化</li>
<li><p>引入第三方库的某一个功能</p>
<p>例子</p>
</li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        publicPath: <span class="string">'./dist/'</span>, <span class="comment">//指定从项目中哪里引入资源 </span></span><br><span class="line">        filename: <span class="string">'[name].bundle.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">        rules: [</span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.js$/</span>,</span><br><span class="line">                use: [</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'babel-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            presets: [<span class="string">'env'</span>],</span><br><span class="line">                            plugins: [</span><br><span class="line">                                <span class="comment">// lodash Tree shaking</span></span><br><span class="line">                                <span class="string">'lodash'</span></span><br><span class="line">                            ]</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                ]</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">    plugins: [</span><br><span class="line">        <span class="keyword">new</span> ExtractTextWebpackPlugin(&#123;</span><br><span class="line">            filename: <span class="string">'[name].min.css'</span>,</span><br><span class="line">            allChunks: <span class="literal">false</span> <span class="comment">//指定提取css范围，true所有import进来的css</span></span><br><span class="line">        &#125;)</span><br><span class="line">        <span class="comment">// Tree shaking</span></span><br><span class="line">        <span class="keyword">new</span> webpack.optimize.UglifyJsPlugin(&#123;</span><br><span class="line">            </span><br><span class="line">        &#125;)</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>有些库不是es模块写的，并不能<code>tree shaking</code>。需要借助其他工具 </p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">npm i babel-loader babel-core babel-preset-env babel-plugin-lodash --save</span><br></pre></td></tr></table></figure>
<blockquote>
<p>lodash Tree不生效</p>
</blockquote>
<ul>
<li><code>lodash-es</code> –&gt; no</li>
<li><code>babel-lugin-lodash</code> —&gt;working</li>
</ul>
<blockquote>
<p>查看模块是否Tree Shaking方式：去第三方库index.js中看模块书写方式是否是es</p>
</blockquote>
<h4 id="3-7-2-CSS-Tree-shaking"><a href="#3-7-2-CSS-Tree-shaking" class="headerlink" title="3.7.2 CSS Tree shaking"></a>3.7.2 CSS Tree shaking</h4><blockquote>
<p>主要使用 <code>purifycss-webpack</code></p>
</blockquote>
<p>例子</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> glob = <span class="built_in">require</span>(<span class="string">'glob-all'</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        publicPath: <span class="string">'./dist/'</span>, <span class="comment">//指定从项目中哪里引入资源 </span></span><br><span class="line">        filename: <span class="string">'[name].bundle.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">        rules: [</span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.js$/</span>,</span><br><span class="line">                use: [</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'babel-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            presets: [<span class="string">'env'</span>],</span><br><span class="line">                            plugins: [</span><br><span class="line">                                <span class="comment">// lodash Tree shaking</span></span><br><span class="line">                                <span class="string">'lodash'</span></span><br><span class="line">                            ]</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                ]</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">    plugins: [</span><br><span class="line">        <span class="keyword">new</span> ExtractTextWebpackPlugin(&#123;</span><br><span class="line">            filename: <span class="string">'[name].min.css'</span>,</span><br><span class="line">            allChunks: <span class="literal">false</span> <span class="comment">//指定提取css范围，true所有import进来的css</span></span><br><span class="line">        &#125;)</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 放到ExtractTextWebpackPlugin后面</span></span><br><span class="line">        <span class="keyword">new</span> PurifyCss(&#123;</span><br><span class="line">            paths: glob.sync([</span><br><span class="line">                path.join(__dirname,<span class="string">'./*.html'</span>),</span><br><span class="line">                path.join(__dirnname,<span class="string">'./src/*.js'</span>)</span><br><span class="line">            ])</span><br><span class="line">        &#125;)</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// Tree shaking</span></span><br><span class="line">        <span class="keyword">new</span> webpack.optimize.UglifyJsPlugin(&#123;</span><br><span class="line">            </span><br><span class="line">        &#125;)</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="四、由浅入深Webpack"><a href="#四、由浅入深Webpack" class="headerlink" title="四、由浅入深Webpack"></a>四、由浅入深Webpack</h2><h3 id="4-1-文件处理"><a href="#4-1-文件处理" class="headerlink" title="4.1 文件处理"></a>4.1 文件处理</h3><h4 id="4-1-1-图片处理"><a href="#4-1-1-图片处理" class="headerlink" title="4.1.1 图片处理"></a>4.1.1 图片处理</h4><ul>
<li><code>css</code>中引入图片</li>
<li>自动合成雪碧图</li>
<li>压缩图片</li>
<li><code>Base64</code>编码</li>
</ul>
<blockquote>
<p>处理需要用到的<code>loader</code></p>
</blockquote>
<ul>
<li><code>file-loader</code> <code>css</code>中引入图片</li>
<li><code>url-loader</code> <code>base64</code>编码</li>
<li><code>img-loader</code> 压缩图片</li>
<li><code>postcss-sprites</code>合成雪碧图</li>
</ul>
<h4 id="4-1-2-处理雪碧图、base64、压缩图片"><a href="#4-1-2-处理雪碧图、base64、压缩图片" class="headerlink" title="4.1.2 处理雪碧图、base64、压缩图片"></a>4.1.2 处理雪碧图、base64、压缩图片</h4><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">         rules: [</span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.(css|less)$/</span>,</span><br><span class="line">                use:</span><br><span class="line">                extractLess.extract(&#123;</span><br><span class="line">                    <span class="comment">// 提取css并不会自动加入到文档中，需要在HTML手动加入css文件</span></span><br><span class="line">                    fallback: &#123;</span><br><span class="line">                        loader: <span class="string">'style-loader'</span>,</span><br><span class="line">                        options: &#123; </span><br><span class="line">                           <span class="comment">//合并多个style为一个</span></span><br><span class="line">                            singleton:<span class="literal">true</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    <span class="comment">// 处理css</span></span><br><span class="line">                    use: [</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'css-loader'</span>,</span><br><span class="line">                            options: &#123;</span><br><span class="line">                               minimize:<span class="literal">true</span>,</span><br><span class="line">                               modules: <span class="literal">true</span>,</span><br><span class="line">                               <span class="comment">// css模块化</span></span><br><span class="line">                               localIdentName: <span class="string">'[path][name]_[local]_[hash:base64:5]'</span></span><br><span class="line">                        &#125;</span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'less-loader'</span></span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'sass-loader'</span></span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'postcss-loader'</span>,</span><br><span class="line">                            options: &#123;</span><br><span class="line">                                ident: <span class="string">'postcss'</span>,</span><br><span class="line">                                plugins: [</span><br><span class="line">                                    <span class="comment">// 合并雪碧图</span></span><br><span class="line">                                    <span class="built_in">require</span>(<span class="string">'postcss-sprites'</span>)(&#123;</span><br><span class="line">                                        <span class="comment">// 指定雪碧图输出路径</span></span><br><span class="line">                                        spritePath: <span class="string">'dist/assets/imgs/sprites'</span>,</span><br><span class="line">                                        retina: <span class="literal">true</span> <span class="comment">// 处理苹果高清retina 图片命名需要 xx@2x.png,对应的图片的css大小设置也要减小一半 </span></span><br><span class="line">                                    &#125;)</span><br><span class="line">                                ]</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                    ]</span><br><span class="line">                &#125;)</span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.(png|jpg|gif)$/</span>,</span><br><span class="line">                use:[</span><br><span class="line">                    <span class="comment">//&#123;</span></span><br><span class="line">                    <span class="comment">//    loader: //'file-loader',//处理图片</span></span><br><span class="line">                    <span class="comment">//    options: &#123;</span></span><br><span class="line">                    <span class="comment">//       publicPath:'',// 使得图片地址可以访问</span></span><br><span class="line">                    <span class="comment">//       outputPath: 'dist/'</span></span><br><span class="line">                    <span class="comment">//       useRelativePath:true</span></span><br><span class="line">                        <span class="comment">//&#125;</span></span><br><span class="line">                    </span><br><span class="line">                    <span class="comment">//&#125;</span></span><br><span class="line">                    <span class="comment">// url-loader会把图片转成base64</span></span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'url-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            name: <span class="string">'[name].min.[ext]'</span> <span class="comment">//5kb内会转成base64 ,否则输出图片路径</span></span><br><span class="line">                            limit: <span class="number">1000</span>, </span><br><span class="line">                            publicPath:<span class="string">''</span>,</span><br><span class="line">                            outputPath: <span class="string">'dist/'</span>,</span><br><span class="line">                            useRelativePath:<span class="literal">true</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    <span class="comment">// 压缩图片</span></span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'img-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            pngquant: &#123;</span><br><span class="line">                                <span class="comment">//图片质量</span></span><br><span class="line">                                quality:<span class="number">80</span></span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    </span><br><span class="line">                ]</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="4-1-2-处理字体文件"><a href="#4-1-2-处理字体文件" class="headerlink" title="4.1.2 处理字体文件"></a>4.1.2 处理字体文件</h4><ul>
<li><code>file-loader</code></li>
<li><code>url-loader</code></li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">         rules: [</span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.(css|less)$/</span>,</span><br><span class="line">                use:</span><br><span class="line">                extractLess.extract(&#123;</span><br><span class="line">                    <span class="comment">// 提取css并不会自动加入到文档中，需要在HTML手动加入css文件</span></span><br><span class="line">                    fallback: &#123;</span><br><span class="line">                        loader: <span class="string">'style-loader'</span>,</span><br><span class="line">                        options: &#123; </span><br><span class="line">                           <span class="comment">//合并多个style为一个</span></span><br><span class="line">                            singleton:<span class="literal">true</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    <span class="comment">// 处理css</span></span><br><span class="line">                    use: [</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'css-loader'</span>,</span><br><span class="line">                            options: &#123;</span><br><span class="line">                               minimize:<span class="literal">true</span>,</span><br><span class="line">                               modules: <span class="literal">true</span>,</span><br><span class="line">                               <span class="comment">// css模块化</span></span><br><span class="line">                               localIdentName: <span class="string">'[path][name]_[local]_[hash:base64:5]'</span></span><br><span class="line">                        &#125;</span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'less-loader'</span></span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'sass-loader'</span></span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'postcss-loader'</span>,</span><br><span class="line">                            options: &#123;</span><br><span class="line">                                ident: <span class="string">'postcss'</span>,</span><br><span class="line">                                plugins: [</span><br><span class="line">                                    <span class="comment">// 合并雪碧图</span></span><br><span class="line">                                    <span class="built_in">require</span>(<span class="string">'postcss-sprites'</span>)(&#123;</span><br><span class="line">                                        <span class="comment">// 指定雪碧图输出路径</span></span><br><span class="line">                                        spritePath: <span class="string">'dist/assets/imgs/sprites'</span>,</span><br><span class="line">                                        retina: <span class="literal">true</span> <span class="comment">// 处理苹果高清retina 图片命名需要 xx@2x.png,对应的图片的css大小设置也要减小一半 </span></span><br><span class="line">                                    &#125;)</span><br><span class="line">                                ]</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                    ]</span><br><span class="line">                &#125;)</span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.(png|jpg|gif)$/</span>,</span><br><span class="line">                use:[</span><br><span class="line">                    <span class="comment">//&#123;</span></span><br><span class="line">                    <span class="comment">//    loader: //'file-loader',//处理图片</span></span><br><span class="line">                    <span class="comment">//    options: &#123;</span></span><br><span class="line">                    <span class="comment">//       publicPath:'',// 使得图片地址可以访问</span></span><br><span class="line">                    <span class="comment">//       outputPath: 'dist/'</span></span><br><span class="line">                    <span class="comment">//       useRelativePath:true</span></span><br><span class="line">                        <span class="comment">//&#125;</span></span><br><span class="line">                    </span><br><span class="line">                    <span class="comment">//&#125;</span></span><br><span class="line">                    <span class="comment">// url-loader会把图片转成base64</span></span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'url-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            name: <span class="string">'[name].min.[ext]'</span> <span class="comment">//5kb内会转成base64 ,否则输出图片路径</span></span><br><span class="line">                            limit: <span class="number">1000</span>, </span><br><span class="line">                            publicPath:<span class="string">''</span>,</span><br><span class="line">                            outputPath: <span class="string">'dist/'</span>,</span><br><span class="line">                            useRelativePath:<span class="literal">true</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    <span class="comment">// 压缩图片</span></span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'img-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            pngquant: &#123;</span><br><span class="line">                                <span class="comment">//图片质量</span></span><br><span class="line">                                quality:<span class="number">80</span></span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    <span class="comment">// 处理字体文件</span></span><br><span class="line">                    &#123;</span><br><span class="line">                        test: <span class="regexp">/\.(eot|woff2|woff|ttf|svg)$/</span>,</span><br><span class="line">                        use: [</span><br><span class="line">                            &#123;</span><br><span class="line">                                loader:<span class="string">'url-loader'</span>,</span><br><span class="line">                                options: &#123;</span><br><span class="line">                                    name: <span class="string">'[name].min.[ext]'</span> <span class="comment">//5kb内会转成base64 ,否则输出图片路径</span></span><br><span class="line">                                    limit: <span class="number">5000</span>, </span><br><span class="line">                                    publicPath:<span class="string">''</span>,</span><br><span class="line">                                    outputPath: <span class="string">'dist/'</span>,</span><br><span class="line">                                    useRelativePath:<span class="literal">true</span></span><br><span class="line">                                &#125;</span><br><span class="line">                            &#125;</span><br><span class="line">                        ]</span><br><span class="line">                    &#125;</span><br><span class="line">                    </span><br><span class="line">                ]</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="4-1-3-处理第三方-JS-库"><a href="#4-1-3-处理第三方-JS-库" class="headerlink" title="4.1.3 处理第三方 JS 库"></a>4.1.3 处理第三方 JS 库</h4><blockquote>
<p>处理第三方库 用到<code>providePlugin</code>、<code>imports-loader</code></p>
</blockquote>
<p><strong>1.providePlugin</strong></p>
<p>以引入<code>jQuery</code>为例</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">npm i jquery</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    plugins: [</span><br><span class="line">        <span class="keyword">new</span> webpack.ProvidePlugin(&#123;</span><br><span class="line">            <span class="comment">// 在全局注入jQuery变量</span></span><br><span class="line">            $:<span class="string">'jquery'</span></span><br><span class="line">        &#125;)</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>引入本地<code>libs</code>中的<code>jQuery</code></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    resolve: &#123;</span><br><span class="line">        alias: &#123;</span><br><span class="line">            <span class="comment">// $确切匹配 把jQuery这个关键字解析到某个目录下</span></span><br><span class="line">            jquery$:path.resolve(__dirname,<span class="string">'src/libs/jquery.min.js'</span>)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    plugins: [</span><br><span class="line">        <span class="keyword">new</span> webpack.ProvidePlugin(&#123;</span><br><span class="line">            <span class="comment">// 在全局注入jQuery变量</span></span><br><span class="line">            $:<span class="string">'jquery'</span></span><br><span class="line">        &#125;)</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>2.imports-loader</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    <span class="built_in">module</span>:&#123;</span><br><span class="line">        rules:[</span><br><span class="line">            &#123;</span><br><span class="line">                test:path.resolve(__dirname,<span class="string">'src/app.js'</span>),</span><br><span class="line">                use:[</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'imports-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            $: <span class="string">'jquery'</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                ]</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="4-2-HTML-in-webpack-自动生成HTML"><a href="#4-2-HTML-in-webpack-自动生成HTML" class="headerlink" title="4.2 HTML in webpack(自动生成HTML)"></a>4.2 HTML in webpack(自动生成HTML)</h3><blockquote>
<p>自动生成<code>HTML</code>，把这个页面需要的<code>js</code>、<code>css</code>插入到页面中</p>
</blockquote>
<h4 id="4-2-1-生成-HTML"><a href="#4-2-1-生成-HTML" class="headerlink" title="4.2.1 生成 HTML"></a>4.2.1 生成 HTML</h4><blockquote>
<p><code>htmlWebpackPlugin</code></p>
</blockquote>
<p>options</p>
<ul>
<li><code>template</code></li>
<li><code>filename</code></li>
<li><code>minify</code> 是否压缩</li>
<li><code>chunks</code> </li>
<li><code>inject</code> 是否让<code>css、js</code>通过标签形式插入到页面中</li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        filename: <span class="string">'[name].bundle.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    plugin:[</span><br><span class="line">        <span class="keyword">new</span> htmlWebpackPlugin(&#123;</span><br><span class="line">            filename:<span class="string">'index.html'</span>, <span class="comment">// 不传默认index.html</span></span><br><span class="line">            template: <span class="string">'./index.html'</span>,<span class="comment">//传入模板</span></span><br><span class="line">            inject:<span class="literal">true</span>,<span class="comment">//控制js\css是否插入到页面</span></span><br><span class="line">            minify: &#123;</span><br><span class="line">                collapseWhitespace:<span class="literal">true</span> <span class="comment">//压缩空格</span></span><br><span class="line">            &#125;,</span><br><span class="line">            chunks:[<span class="string">'app'</span>]<span class="comment">//指定chunks会把跟这个入口相关的chunks插入到页面中</span></span><br><span class="line">        &#125;)</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="4-2-2-HTML-中引入图片"><a href="#4-2-2-HTML-中引入图片" class="headerlink" title="4.2.2 HTML 中引入图片"></a>4.2.2 HTML 中引入图片</h4><blockquote>
<p>需要用到<code>html-loader</code></p>
</blockquote>
<p><strong>html-loader</strong></p>
<p>options</p>
<ul>
<li><code>attrs: [img:src]</code></li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        filename: <span class="string">'[name].bundle.js'</span>,</span><br><span class="line">        publicPath:<span class="string">'/'</span> <span class="comment">//网站路径为/ 图片等资源引用不会发生错误</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="built_in">module</span>:&#123;</span><br><span class="line">        rules:[</span><br><span class="line">            &#123;</span><br><span class="line">                loader: <span class="string">'url-loader'</span>,</span><br><span class="line">                options: &#123;</span><br><span class="line">                    name: <span class="string">'[name].min.[ext]'</span> <span class="comment">//5kb内会转成base64 ,否则输出图片路径</span></span><br><span class="line">                    limit: <span class="number">1000</span>, </span><br><span class="line">                    publicPath:<span class="string">''</span>,</span><br><span class="line">                    outputPath: <span class="string">'assets/imgs/'</span>,</span><br><span class="line">                    <span class="comment">//useRelativePath:true // 这里不能使用这个 因为图片路径在HTML中、css中都存在，打包的时候图片会放错地方。需要用到绝对路径，在output指定publicPath:'/'</span></span><br><span class="line">                &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            <span class="comment">// 处理HTML中的图片引用路径问题</span></span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.html$/</span>,</span><br><span class="line">                use: [</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'html-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            attrs: [<span class="string">'img:src'</span>,<span class="string">'img:data-src'</span>]</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                ]</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>require在HTML中引入图片</strong></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">"$&#123;require('./public/imgs/xx.png)&#125;"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<h4 id="4-2-3-配合优化"><a href="#4-2-3-配合优化" class="headerlink" title="4.2.3 配合优化"></a>4.2.3 配合优化</h4><blockquote>
<p>提前载入webpack加载代码</p>
</blockquote>
<ul>
<li><code>inline-manifest-webpack-plugin</code></li>
<li><code>html-webpack-inline-chunk-plugin</code></li>
</ul>
<p>建议使用 <code>html-webpack-inline-chunk-plugin</code></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">npm i html-webpack-inline-chunk-plugin</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> HTMLInlieChunk = <span class="built_in">require</span>(<span class="string">'html-webpack-inline-chunk-plugin'</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        filename: <span class="string">'[name].bundle.js'</span>,</span><br><span class="line">        publicPath:<span class="string">'/'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    plugin:[</span><br><span class="line">        <span class="keyword">new</span> htmlWebpackPlugin(&#123;</span><br><span class="line">            filename:<span class="string">'index.html'</span>, <span class="comment">// 不传默认index.html</span></span><br><span class="line">            template: <span class="string">'./index.html'</span>,<span class="comment">//传入模板</span></span><br><span class="line">            inject:<span class="literal">true</span>,<span class="comment">//控制js\css是否插入到页面</span></span><br><span class="line">            minify: &#123;</span><br><span class="line">                collapseWhitespace:<span class="literal">true</span> <span class="comment">//压缩空格</span></span><br><span class="line">            &#125;,</span><br><span class="line">            chunks:[<span class="string">'app'</span>]<span class="comment">//指定chunks会把跟这个入口相关的chunks插入到页面中</span></span><br><span class="line">        &#125;)</span><br><span class="line">        <span class="keyword">new</span> webpack.mdtimize.CommonsChunkPlugin(&#123;</span><br><span class="line">            name: <span class="string">'manifest'</span></span><br><span class="line">        &#125;)</span><br><span class="line">        <span class="keyword">new</span> HTMLInlieChunk(&#123;</span><br><span class="line">            inlineChunks: [<span class="string">'manifest'</span>] <span class="comment">//把webpack生成的manifest提取到HTML文件script中，减少请求</span></span><br><span class="line">        &#125;)</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="五、Webpack-环境配置"><a href="#五、Webpack-环境配置" class="headerlink" title="五、Webpack 环境配置"></a>五、Webpack 环境配置</h2><h3 id="5-1-Webpack-Watch-Mode"><a href="#5-1-Webpack-Watch-Mode" class="headerlink" title="5.1 Webpack Watch Mode"></a>5.1 Webpack Watch Mode</h3><figure class="highlight js"><table><tr><td class="code"><pre><span class="line">webpack --watch</span><br><span class="line"></span><br><span class="line"><span class="comment">// 简写</span></span><br><span class="line">webpack -w</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//webpack.config.js</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> webpack = <span class="built_in">require</span>(<span class="string">'wepback'</span>)</span><br><span class="line"><span class="keyword">var</span> PurifyWebpack = <span class="built_in">require</span>(<span class="string">'pruifycss-webpack'</span>)</span><br><span class="line"><span class="keyword">var</span> ExtractTextWebpackPlugin = <span class="built_in">require</span>(<span class="string">'extract-text-webpack-plugin'</span>)</span><br><span class="line"><span class="keyword">var</span> HtmlWebpackPlugin = <span class="built_in">require</span>(<span class="string">'html-webpack-plugin'</span>)</span><br><span class="line"><span class="keyword">var</span> CleanWebpack = <span class="built_in">require</span>(<span class="string">'clean-webpacl-plugin'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"><span class="keyword">var</span> glob = rquire(<span class="string">'glob-all'</span>)<span class="comment">//处理多个路径</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> extractLess = <span class="keyword">new</span> ExtractTextWebpackPlugin(&#123;</span><br><span class="line">    filename: <span class="string">'css/[name]-bundle-[hash:5].css'</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        filename: <span class="string">'[name]-bundle-[hash:5].js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="built_in">module</span>:&#123;</span><br><span class="line">        rules: [</span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.(css|less)$/</span>,</span><br><span class="line">                use:</span><br><span class="line">                extractLess.extract(&#123;</span><br><span class="line">                    <span class="comment">// 提取css并不会自动加入到文档中，需要在HTML手动加入css文件</span></span><br><span class="line">                    fallback: &#123;</span><br><span class="line">                        loader: <span class="string">'style-loader'</span>,</span><br><span class="line">                        options: &#123; </span><br><span class="line">                           <span class="comment">//合并多个style为一个</span></span><br><span class="line">                            singleton:<span class="literal">true</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    <span class="comment">// 处理css</span></span><br><span class="line">                    use: [</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'css-loader'</span>,</span><br><span class="line">                            options: &#123;</span><br><span class="line">                               minimize:<span class="literal">true</span>,</span><br><span class="line">                               modules: <span class="literal">true</span>,</span><br><span class="line">                               <span class="comment">// css模块化</span></span><br><span class="line">                               localIdentName: <span class="string">'[path][name]_[local]_[hash:base64:5]'</span></span><br><span class="line">                        &#125;</span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'less-loader'</span></span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'sass-loader'</span></span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            loader: <span class="string">'postcss-loader'</span>,</span><br><span class="line">                            options: &#123;</span><br><span class="line">                                ident: <span class="string">'postcss'</span>,</span><br><span class="line">                                plugins: [</span><br><span class="line">                                    <span class="comment">// 合并雪碧图</span></span><br><span class="line">                                    <span class="built_in">require</span>(<span class="string">'postcss-sprites'</span>)(&#123;</span><br><span class="line">                                        <span class="comment">// 指定雪碧图输出路径</span></span><br><span class="line">                                        spritePath: <span class="string">'dist/assets/imgs/sprites'</span>,</span><br><span class="line">                                        retina: <span class="literal">true</span> <span class="comment">// 处理苹果高清retina 图片命名需要 xx@2x.png,对应的图片的css大小设置也要减小一半 </span></span><br><span class="line">                                    &#125;)</span><br><span class="line">                                ]</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                    ]</span><br><span class="line">                &#125;)</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">    plugin: [</span><br><span class="line">        <span class="keyword">new</span> CleanWebpack()</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="5-2-Webpack-Dev-Server"><a href="#5-2-Webpack-Dev-Server" class="headerlink" title="5.2 Webpack Dev Server"></a>5.2 Webpack Dev Server</h3><h4 id="5-2-1-Dev-Server"><a href="#5-2-1-Dev-Server" class="headerlink" title="5.2.1 Dev Server"></a>5.2.1 Dev Server</h4><blockquote>
<p>不能用来直接打包文件，<code>Dev Server</code>搭建本地开发，文件存在内存中</p>
</blockquote>
<p><strong>特性</strong></p>
<ul>
<li><code>live reloading</code></li>
<li>路径重定向</li>
<li>支持<code>HTTPS</code></li>
<li>浏览器中显示编译错误</li>
<li>接口代理</li>
<li>模块热更新</li>
</ul>
<p><strong>dev server</strong></p>
<ul>
<li><code>inline</code></li>
<li><code>contentBase</code></li>
<li><code>port</code></li>
<li><code>histApiFllback</code></li>
<li><code>https</code></li>
<li><code>proxy</code></li>
<li><code>hot</code></li>
<li><code>openpage</code></li>
<li><code>lazy</code></li>
<li><code>overlay</code> 开启错误遮罩</li>
</ul>
<p><strong>使用</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">&quot;script&quot;&#123;</span><br><span class="line">    // 启动</span><br><span class="line">    &quot;server&quot;: &quot;webpack-dev-server --open&quot; </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    </span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        publicPath: <span class="string">'/'</span>,</span><br><span class="line">        filename: <span class="string">'[name].[hash:5].js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    </span><br><span class="line">    devServer: &#123;</span><br><span class="line">        port: <span class="number">9001</span>,</span><br><span class="line">        <span class="comment">// 输入任意路径都不会出现404 都会重定向</span></span><br><span class="line">       <span class="comment">// historyApiFallback: true</span></span><br><span class="line">        historyApiFallback: &#123;</span><br><span class="line">            <span class="comment">//从一个确定的url指向对应的文件</span></span><br><span class="line">            <span class="comment">//rewrites: [</span></span><br><span class="line">            <span class="comment">//    &#123;</span></span><br><span class="line">            <span class="comment">//        from: '/pages/a',// 可以写正则</span></span><br><span class="line">           <span class="comment">//         to: '/pages/a.html'</span></span><br><span class="line">            <span class="comment">//    &#125;</span></span><br><span class="line">            rewrites: [</span><br><span class="line">                &#123;</span><br><span class="line">                    <span class="keyword">from</span>: <span class="regexp">/^\/([a-zA-Z0-9]+\/?)([a-zA-Z0-9]+)/</span></span><br><span class="line">                    to: <span class="function"><span class="keyword">function</span>(<span class="params">context</span>)</span>&#123;</span><br><span class="line">                        <span class="keyword">return</span> <span class="string">'/'</span> + context.match[<span class="number">1</span>] + context.match[<span class="number">2</span>] + <span class="string">'.html'</span></span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            ]</span><br><span class="line">            ]</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="5-2-2-proxy代理远程接口"><a href="#5-2-2-proxy代理远程接口" class="headerlink" title="5.2.2 proxy代理远程接口"></a>5.2.2 proxy代理远程接口</h4><ul>
<li>代理远程接口请求</li>
<li><code>http-proxy-middleware</code></li>
<li><code>devServer.proxy</code></li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    </span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        publicPath: <span class="string">'/'</span>,</span><br><span class="line">        filename: <span class="string">'[name].[hash:5].js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    </span><br><span class="line">    devServer: &#123;</span><br><span class="line">        port: <span class="number">9001</span>,</span><br><span class="line">        <span class="comment">// 输入任意路径都不会出现404 都会重定向</span></span><br><span class="line">       <span class="comment">// historyApiFallback: true</span></span><br><span class="line">        historyApiFallback: &#123;</span><br><span class="line">            <span class="comment">//从一个确定的url指向对应的文件</span></span><br><span class="line">            <span class="comment">//rewrites: [</span></span><br><span class="line">            <span class="comment">//    &#123;</span></span><br><span class="line">            <span class="comment">//        from: '/pages/a',// 可以写正则</span></span><br><span class="line">           <span class="comment">//         to: '/pages/a.html'</span></span><br><span class="line">            <span class="comment">//    &#125;</span></span><br><span class="line">            rewrites: [</span><br><span class="line">                &#123;</span><br><span class="line">                    <span class="keyword">from</span>: <span class="regexp">/^\/([a-zA-Z0-9]+\/?)([a-zA-Z0-9]+)/</span></span><br><span class="line">                    to: <span class="function"><span class="keyword">function</span>(<span class="params">context</span>)</span>&#123;</span><br><span class="line">                        <span class="keyword">return</span> <span class="string">'/'</span> + context.match[<span class="number">1</span>] + context.match[<span class="number">2</span>] + <span class="string">'.html'</span></span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            ]</span><br><span class="line">            ]</span><br><span class="line">        &#125;,</span><br><span class="line">        proxy: &#123;</span><br><span class="line">            <span class="string">'/api'</span>: &#123;</span><br><span class="line">                target: <span class="string">'https://blog.poetries.top'</span>,<span class="comment">//代理到服务器</span></span><br><span class="line">                changeOrigin:<span class="literal">true</span>,</span><br><span class="line">                logLevel: <span class="string">'debug'</span>,</span><br><span class="line">                <span class="comment">// pathRewite: &#123; &#125;,</span></span><br><span class="line">                headers:&#123;&#125;<span class="comment">// 请求头</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="5-2-3-模块热更新"><a href="#5-2-3-模块热更新" class="headerlink" title="5.2.3 模块热更新"></a>5.2.3 模块热更新</h4><ul>
<li>保持应用的数据状态</li>
<li>节省调试时间</li>
<li><p>不需要刷新</p>
</li>
<li><p><code>devServer.hot</code></p>
</li>
<li><code>webpack.HotModleReplacementPlugin</code></li>
<li><code>webpack.NamedModulesPlugin</code> 看到模块更新的路径</li>
</ul>
<p><strong>Module Hot Reloading</strong></p>
<ul>
<li><code>module.hot</code></li>
<li><code>module.hot.accept</code></li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    </span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        publicPath: <span class="string">'/'</span>,</span><br><span class="line">        filename: <span class="string">'[name].[hash:5].js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    </span><br><span class="line">    devServer: &#123;</span><br><span class="line">        port: <span class="number">9001</span>,</span><br><span class="line">        <span class="comment">// 输入任意路径都不会出现404 都会重定向</span></span><br><span class="line">       <span class="comment">// historyApiFallback: true</span></span><br><span class="line">        historyApiFallback: &#123;</span><br><span class="line">            <span class="comment">//从一个确定的url指向对应的文件</span></span><br><span class="line">            <span class="comment">//rewrites: [</span></span><br><span class="line">            <span class="comment">//    &#123;</span></span><br><span class="line">            <span class="comment">//        from: '/pages/a',// 可以写正则</span></span><br><span class="line">           <span class="comment">//         to: '/pages/a.html'</span></span><br><span class="line">            <span class="comment">//    &#125;</span></span><br><span class="line">            rewrites: [</span><br><span class="line">                &#123;</span><br><span class="line">                    <span class="keyword">from</span>: <span class="regexp">/^\/([a-zA-Z0-9]+\/?)([a-zA-Z0-9]+)/</span></span><br><span class="line">                    to: <span class="function"><span class="keyword">function</span>(<span class="params">context</span>)</span>&#123;</span><br><span class="line">                        <span class="keyword">return</span> <span class="string">'/'</span> + context.match[<span class="number">1</span>] + context.match[<span class="number">2</span>] + <span class="string">'.html'</span></span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            ]</span><br><span class="line">            ]</span><br><span class="line">        &#125;,</span><br><span class="line">        hot:<span class="literal">true</span>,<span class="comment">//开启模块热更新</span></span><br><span class="line">        hotOnly:<span class="literal">true</span>,</span><br><span class="line">        proxy: &#123;</span><br><span class="line">            <span class="string">'/api'</span>: &#123;</span><br><span class="line">                target: <span class="string">'https://blog.poetries.top'</span>,<span class="comment">//代理到服务器</span></span><br><span class="line">                changeOrigin:<span class="literal">true</span>,</span><br><span class="line">                logLevel: <span class="string">'debug'</span>,</span><br><span class="line">                <span class="comment">// pathRewite: &#123; &#125;,</span></span><br><span class="line">                headers:&#123;&#125;<span class="comment">// 请求头</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    plugin:[</span><br><span class="line">        <span class="comment">// 模块热更新插件</span></span><br><span class="line">        <span class="keyword">new</span> webpack.HotModuleReplacementPlugin()</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 输出热更新路径</span></span><br><span class="line">        <span class="keyword">new</span> webpack.NamedModulesPlugin()</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>模块热更新配置</strong></p>
<blockquote>
<p>需要通过module.hot</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">f (<span class="built_in">module</span>.hot) &#123;</span><br><span class="line">  <span class="built_in">module</span>.hot.accept(<span class="string">'./library.js'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// Do something with the updated library module...</span></span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="5-2-4-开启调试SourceMap"><a href="#5-2-4-开启调试SourceMap" class="headerlink" title="5.2.4 开启调试SourceMap"></a>5.2.4 开启调试SourceMap</h4><p><strong>Source Map调试</strong></p>
<p>把生成以后代码和之前的做一个映射</p>
<blockquote>
<p>开启Source Map方式</p>
</blockquote>
<p><strong><code>JS Source Map</code>设置</strong></p>
<p>develpoment</p>
<ul>
<li><code>eval</code></li>
<li><code>eval-source-map</code></li>
<li><code>cheap-eval-source-map</code></li>
<li><code>cheap-module-eval-source-map</code></li>
</ul>
<blockquote>
<p>推荐使用<code>cheap-module-source-map</code></p>
</blockquote>
<p>production</p>
<ul>
<li><code>source-map</code></li>
<li><code>hidden-source-map</code></li>
<li><code>nosource-source-map</code></li>
</ul>
<blockquote>
<p>推荐使用<code>source-map</code></p>
</blockquote>
<p><strong><code>CSS Source Map</code>设置</strong></p>
<blockquote>
<p>改变<code>loader</code>的<code>options</code>选项</p>
</blockquote>
<ul>
<li><code>css-loader.options.soucemap</code></li>
<li><code>less-loader.options.soucemap</code></li>
<li><code>sass-loader.options.soucemap</code></li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    </span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        publicPath: <span class="string">'/'</span>,</span><br><span class="line">        filename: <span class="string">'[name].[hash:5].js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">        <span class="comment">// 处理css的每个loader加上sourceMap: true 观察css样式 可以看到对应的行号</span></span><br><span class="line">        rules: [</span><br><span class="line">            test: <span class="regexp">/\.less/</span>,</span><br><span class="line">            use: [</span><br><span class="line">                &#123;</span><br><span class="line">                    loader: <span class="string">'style-loader'</span>,</span><br><span class="line">                    options: &#123;</span><br><span class="line">                        <span class="comment">// singleton: true,会导致css的sourceMap不生效</span></span><br><span class="line">                        <span class="comment">//singleton: true,</span></span><br><span class="line">                        sourceMap: <span class="literal">true</span></span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;,</span><br><span class="line">                &#123;</span><br><span class="line">                    loader: <span class="string">'css-loader'</span>,</span><br><span class="line">                    options: &#123;</span><br><span class="line">                        importLoaders: <span class="number">2</span>,</span><br><span class="line">                        sourceMap: <span class="literal">true</span></span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;,</span><br><span class="line">                &#123;</span><br><span class="line">                    loader: <span class="string">'less-loader'</span>,</span><br><span class="line">                    options: &#123;</span><br><span class="line">                        sourceMap: <span class="literal">true</span></span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            ]</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">    devtool: <span class="string">'cheap-module-eval-source-map'</span>,<span class="comment">//开启sourcemap</span></span><br><span class="line">    devServer: &#123;</span><br><span class="line">        port: <span class="number">9001</span>,</span><br><span class="line">        <span class="comment">// 输入任意路径都不会出现404 都会重定向</span></span><br><span class="line">       <span class="comment">// historyApiFallback: true</span></span><br><span class="line">        historyApiFallback: &#123;</span><br><span class="line">            <span class="comment">//从一个确定的url指向对应的文件</span></span><br><span class="line">            <span class="comment">//rewrites: [</span></span><br><span class="line">            <span class="comment">//    &#123;</span></span><br><span class="line">            <span class="comment">//        from: '/pages/a',// 可以写正则</span></span><br><span class="line">           <span class="comment">//         to: '/pages/a.html'</span></span><br><span class="line">            <span class="comment">//    &#125;</span></span><br><span class="line">            rewrites: [</span><br><span class="line">                &#123;</span><br><span class="line">                    <span class="keyword">from</span>: <span class="regexp">/^\/([a-zA-Z0-9]+\/?)([a-zA-Z0-9]+)/</span></span><br><span class="line">                    to: <span class="function"><span class="keyword">function</span>(<span class="params">context</span>)</span>&#123;</span><br><span class="line">                        <span class="keyword">return</span> <span class="string">'/'</span> + context.match[<span class="number">1</span>] + context.match[<span class="number">2</span>] + <span class="string">'.html'</span></span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            ]</span><br><span class="line">            ]</span><br><span class="line">        &#125;,</span><br><span class="line">        hot:<span class="literal">true</span>,<span class="comment">//开启模块热更新</span></span><br><span class="line">        hotOnly:<span class="literal">true</span>,</span><br><span class="line">        overlay:<span class="literal">true</span>,<span class="comment">//错误提示</span></span><br><span class="line">        proxy: &#123;</span><br><span class="line">            <span class="string">'/api'</span>: &#123;</span><br><span class="line">                target: <span class="string">'https://blog.poetries.top'</span>,<span class="comment">//代理到服务器</span></span><br><span class="line">                changeOrigin:<span class="literal">true</span>,</span><br><span class="line">                logLevel: <span class="string">'debug'</span>,</span><br><span class="line">                <span class="comment">// pathRewite: &#123; &#125;,</span></span><br><span class="line">                headers:&#123;&#125;<span class="comment">// 请求头</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    plugin:[</span><br><span class="line">        <span class="comment">// 模块热更新插件</span></span><br><span class="line">        <span class="keyword">new</span> webpack.HotModuleReplacementPlugin()</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 输出热更新路径</span></span><br><span class="line">        <span class="keyword">new</span> webpack.NamedModulesPlugin()</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="5-2-5-设置-ESLint-检查代码格式"><a href="#5-2-5-设置-ESLint-检查代码格式" class="headerlink" title="5.2.5 设置 ESLint 检查代码格式"></a>5.2.5 设置 ESLint 检查代码格式</h4><ul>
<li><code>eslint</code></li>
<li><code>eslint-loader</code></li>
<li><code>esling-plugin-html</code></li>
<li><code>eslint-frindly-formatter</code> 友好提示错误</li>
</ul>
<p><strong>配置eslint</strong></p>
<ul>
<li><code>wepback config</code> 新增<code>loader</code></li>
<li><code>.eslintrc</code>或者在<code>package.json</code>的<code>eslintConfig</code>中写</li>
</ul>
<blockquote>
<p>配置eslint的规范，推荐使用JavaScript standard style(<a href="https://standardjs.com" target="_blank" rel="noopener">https://standardjs.com</a>)</p>
</blockquote>
<p>需要安装以下插件</p>
<ul>
<li><code>eslint-config-standard</code></li>
<li><code>eslint-plugin-promise</code></li>
<li><code>eslint-plugin-standard</code></li>
<li><code>eslint-plugin-import</code></li>
<li><code>eslint-plugin-node</code></li>
</ul>
<p><strong>eslint-loader</strong></p>
<ul>
<li><code>options.failOnWarning</code> 出现警告</li>
<li><code>options.failOnError</code></li>
<li><code>options.formatter</code></li>
<li><code>options.outputReport</code></li>
</ul>
<blockquote>
<p>设置 <code>devServer.overlay</code>在浏览器中看提示的错误</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// .eslintrc</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    root: <span class="literal">true</span>,</span><br><span class="line">    extends: <span class="string">'standard'</span>,</span><br><span class="line">    plugins: [],</span><br><span class="line">    env: &#123;</span><br><span class="line">        browsers: <span class="literal">true</span>,</span><br><span class="line">        node: <span class="literal">true</span> <span class="comment">// node环境</span></span><br><span class="line">    &#125;,</span><br><span class="line">    rules: &#123;</span><br><span class="line">        <span class="comment">// 缩进</span></span><br><span class="line">        indent: [<span class="string">'error'</span>, <span class="number">4</span>],</span><br><span class="line">        </span><br><span class="line">        <span class="comment">//换行</span></span><br><span class="line">        <span class="string">"eol-last"</span>: [<span class="string">'error'</span>, <span class="string">'never'</span>]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">        app: <span class="string">'./src/app.js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    </span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        publicPath: <span class="string">'/'</span>,</span><br><span class="line">        filename: <span class="string">'[name].[hash:5].js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">        <span class="comment">// 处理css的每个loader加上sourceMap: true 观察css样式 可以看到对应的行号</span></span><br><span class="line">        rules: [</span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.js$/</span>,</span><br><span class="line">                include: [path.resolve(__dirname,<span class="string">'src/'</span>)],</span><br><span class="line">                exclude: [path.resolve(__dirname,<span class="string">'src/libs'</span>)],</span><br><span class="line">                use: [</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'babel-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            presets: [<span class="string">'env'</span>]</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    <span class="comment">//eslint-loader需要在babel-loader之后处理</span></span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'eslint-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            formatter: <span class="built_in">require</span>(<span class="string">'eslint-frindly-formatter'</span>)</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                ]</span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                test: <span class="regexp">/\.less/</span>,</span><br><span class="line">                use: [</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'style-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            <span class="comment">// singleton: true,会导致css的sourceMap不生效</span></span><br><span class="line">                            <span class="comment">//singleton: true,</span></span><br><span class="line">                            sourceMap: <span class="literal">true</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'css-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            importLoaders: <span class="number">2</span>,</span><br><span class="line">                            sourceMap: <span class="literal">true</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    &#123;</span><br><span class="line">                        loader: <span class="string">'less-loader'</span>,</span><br><span class="line">                        options: &#123;</span><br><span class="line">                            sourceMap: <span class="literal">true</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                ]</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">    devtool: <span class="string">'cheap-module-eval-source-map'</span>,<span class="comment">//开启sourcemap</span></span><br><span class="line">    devServer: &#123;</span><br><span class="line">        port: <span class="number">9001</span>,</span><br><span class="line">        <span class="comment">// 输入任意路径都不会出现404 都会重定向</span></span><br><span class="line">       <span class="comment">// historyApiFallback: true</span></span><br><span class="line">        historyApiFallback: &#123;</span><br><span class="line">            <span class="comment">//从一个确定的url指向对应的文件</span></span><br><span class="line">            <span class="comment">//rewrites: [</span></span><br><span class="line">            <span class="comment">//    &#123;</span></span><br><span class="line">            <span class="comment">//        from: '/pages/a',// 可以写正则</span></span><br><span class="line">           <span class="comment">//         to: '/pages/a.html'</span></span><br><span class="line">            <span class="comment">//    &#125;</span></span><br><span class="line">            rewrites: [</span><br><span class="line">                &#123;</span><br><span class="line">                    <span class="keyword">from</span>: <span class="regexp">/^\/([a-zA-Z0-9]+\/?)([a-zA-Z0-9]+)/</span></span><br><span class="line">                    to: <span class="function"><span class="keyword">function</span>(<span class="params">context</span>)</span>&#123;</span><br><span class="line">                        <span class="keyword">return</span> <span class="string">'/'</span> + context.match[<span class="number">1</span>] + context.match[<span class="number">2</span>] + <span class="string">'.html'</span></span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            ]</span><br><span class="line">            ]</span><br><span class="line">        &#125;,</span><br><span class="line">        hot:<span class="literal">true</span>,<span class="comment">//开启模块热更新</span></span><br><span class="line">        hotOnly:<span class="literal">true</span>,</span><br><span class="line">        overlay:<span class="literal">true</span>,<span class="comment">//错误提示</span></span><br><span class="line">        proxy: &#123;</span><br><span class="line">            <span class="string">'/api'</span>: &#123;</span><br><span class="line">                target: <span class="string">'http://blog.poetries.top'</span>,<span class="comment">//代理到服务器</span></span><br><span class="line">                changeOrigin:<span class="literal">true</span>,</span><br><span class="line">                logLevel: <span class="string">'debug'</span>,</span><br><span class="line">                <span class="comment">// pathRewite: &#123; &#125;,</span></span><br><span class="line">                headers:&#123;&#125;<span class="comment">// 请求头</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    plugin:[</span><br><span class="line">        <span class="comment">// 模块热更新插件</span></span><br><span class="line">        <span class="keyword">new</span> webpack.HotModuleReplacementPlugin()</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 输出热更新路径</span></span><br><span class="line">        <span class="keyword">new</span> webpack.NamedModulesPlugin()</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="5-2-6-区分开发环境-和-生产环境"><a href="#5-2-6-区分开发环境-和-生产环境" class="headerlink" title="5.2.6 区分开发环境 和 生产环境"></a>5.2.6 区分开发环境 和 生产环境</h4><p><strong>开发环境</strong></p>
<ul>
<li>模块热更新</li>
<li><code>sourceMap</code></li>
<li>接口代理</li>
<li>代码规范检查</li>
</ul>
<p><strong>生产环境</strong></p>
<ul>
<li>提取公共代码</li>
<li>压缩</li>
<li>文件压缩或<code>base64</code>编码</li>
<li>去除无用的代码</li>
</ul>
<p><strong>共同点</strong></p>
<ul>
<li>入口一致</li>
<li>loader处理</li>
<li>解析配置一致</li>
</ul>
<blockquote>
<p>使用<code>webpack-merge</code>合并公共配置</p>
</blockquote>
<ul>
<li><code>webpack.dev.conf.js</code></li>
<li><code>wepback.prod.conf.js</code></li>
<li><code>webpack.common.conf.js</code></li>
</ul>
<figure class="highlight"><table><tr><td class="code"><pre><span class="line">"scripts":&#123;</span><br><span class="line">    "server": "wepback-dev-server --env development --open --config build/webpack.common.config.js",</span><br><span class="line">    "build": "wepback --env production --open --config build/webpack.common.config.js"</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>公共配置 <code>build/webpack.common.conf.js</code></p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> merge = <span class="built_in">require</span>(<span class="string">'webpack-merge'</span>)</span><br><span class="line"><span class="keyword">const</span> webpack = <span class="built_in">require</span>(<span class="string">'webpack'</span>)</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> chalk = <span class="built_in">require</span>(<span class="string">'chalk'</span>)</span><br><span class="line"><span class="keyword">const</span> ExtractTextWebpackPlugin = <span class="built_in">require</span>(<span class="string">'extract-text-webpack-plugin'</span>)</span><br><span class="line"><span class="keyword">const</span> HtmlWebpackPlugin = <span class="built_in">require</span>(<span class="string">'html-webpack-plugin'</span>)</span><br><span class="line"><span class="keyword">const</span> ProgressBarPlugin = <span class="built_in">require</span>(<span class="string">'progress-bar-webpack-plugin'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> developmentConfig = <span class="built_in">require</span>(<span class="string">'./webpack.dev.conf'</span>)</span><br><span class="line"><span class="keyword">const</span> productionConfig = <span class="built_in">require</span>(<span class="string">'./webpack.prod.conf'</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 根据环境变量生成配置</span></span><br><span class="line"><span class="keyword">const</span> generateConfig = <span class="function"><span class="params">env</span> =&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> extractLess = <span class="keyword">new</span> ExtractTextWebpackPlugin(&#123;</span><br><span class="line">        filename: <span class="string">'css/[name]-bundle-[hash:5].css'</span></span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="keyword">const</span> scriptLoader = [</span><br><span class="line">      <span class="string">'babel-loader'</span></span><br><span class="line">    ].concat(env === <span class="string">'production'</span></span><br><span class="line">      ? []</span><br><span class="line">      : [&#123;</span><br><span class="line">          loader: <span class="string">'eslint-loader'</span>,</span><br><span class="line">          options: &#123;</span><br><span class="line">              formatter: <span class="built_in">require</span>(<span class="string">'eslint-friendly-formatter'</span>)</span><br><span class="line">          &#125;</span><br><span class="line">      &#125;]</span><br><span class="line">    )</span><br><span class="line">    <span class="keyword">const</span> cssLoaders = [</span><br><span class="line">      &#123;</span><br><span class="line">          loader: <span class="string">'css-loader'</span>,</span><br><span class="line">          options: &#123;</span><br><span class="line">              importLoaders: <span class="number">2</span>,</span><br><span class="line">              sourceMap: env===<span class="string">'development'</span></span><br><span class="line">          &#125;</span><br><span class="line">      &#125;,</span><br><span class="line">      &#123;</span><br><span class="line">        loader: <span class="string">"postcss-loader"</span>,</span><br><span class="line">        options: &#123;</span><br><span class="line">          ident: <span class="string">"postcss"</span>,</span><br><span class="line">          sourceMap: env===<span class="string">'development'</span>,</span><br><span class="line">          plugins: [</span><br><span class="line"></span><br><span class="line">          ].concat(env===<span class="string">'production'</span></span><br><span class="line">            ? <span class="built_in">require</span>(<span class="string">'postcss-sprites'</span>)(&#123;</span><br><span class="line">              spritePath: <span class="string">'build/assets/imgs/sprites'</span>,</span><br><span class="line">              retina: <span class="literal">true</span></span><br><span class="line">            &#125;)</span><br><span class="line">            :[]</span><br><span class="line">          )</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;,</span><br><span class="line">      &#123;</span><br><span class="line">          loader: <span class="string">'less-loader'</span>,</span><br><span class="line">          options: &#123;</span><br><span class="line">              sourceMap: env===<span class="string">'development'</span></span><br><span class="line">          &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    ]</span><br><span class="line">    <span class="keyword">const</span> styleLoader = env === <span class="string">'production'</span></span><br><span class="line">          <span class="comment">// 线上需要提取css成文件</span></span><br><span class="line">          ? extractLess.extract(&#123;</span><br><span class="line">            fallback:<span class="string">'style-loader'</span>,</span><br><span class="line">            use: cssLoaders</span><br><span class="line">          &#125;)</span><br><span class="line">          : [<span class="string">'style-loader'</span>].concat(cssLoaders)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> fileLoader = env === <span class="string">'development'</span></span><br><span class="line">        ? [&#123;</span><br><span class="line">            loader: <span class="string">'file-loader'</span>,</span><br><span class="line">            options: &#123;</span><br><span class="line">              name: <span class="string">'[name]-[hash:5].[ext]'</span>,</span><br><span class="line">              outputPath: <span class="string">'assets/imgs/'</span></span><br><span class="line">            &#125;</span><br><span class="line">          &#125;]</span><br><span class="line">        : [&#123;</span><br><span class="line">          loader: <span class="string">'url-loader'</span>,</span><br><span class="line">          options: &#123;</span><br><span class="line">            name: <span class="string">'[name]-[hash:5].[ext]'</span>,</span><br><span class="line">            limit: <span class="number">1000</span>,<span class="comment">//1k</span></span><br><span class="line">            outputPath: <span class="string">'assets/imgs/'</span></span><br><span class="line">          &#125;</span><br><span class="line">        &#125;]</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">      entry: &#123;</span><br><span class="line">          app: <span class="string">'./src/index.js'</span></span><br><span class="line">      &#125;,</span><br><span class="line">      output: &#123;</span><br><span class="line">          path: path.resolve(__dirname, <span class="string">'../build'</span>),</span><br><span class="line">          publicPath: <span class="string">'/'</span>,</span><br><span class="line">          filename: <span class="string">'[name]-bundle-[hash:5].js'</span></span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="comment">// 路径解析</span></span><br><span class="line">      resolve: &#123;</span><br><span class="line">          alias: &#123;</span><br><span class="line">              <span class="comment">// jquery$: path.resolve(__dirname, '../src/libs/jquery.min.js')</span></span><br><span class="line">          &#125;</span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="built_in">module</span>: &#123;</span><br><span class="line">          rules: [</span><br><span class="line">              &#123;</span><br><span class="line">                  test: <span class="regexp">/\.(js|jsx)$/</span>,</span><br><span class="line">                  include: [path.resolve(__dirname,<span class="string">'../src/'</span>)],</span><br><span class="line">                  exclude : <span class="regexp">/node_modules/</span>,</span><br><span class="line">                  use: scriptLoader</span><br><span class="line">              &#125;,</span><br><span class="line">              &#123;</span><br><span class="line">                  test: <span class="regexp">/\.(less|css|scss)/</span>,</span><br><span class="line">                  use: styleLoader</span><br><span class="line">              &#125;,</span><br><span class="line">              &#123;</span><br><span class="line">                test: <span class="regexp">/\.(png|jpg|jpeg|gif)$/</span>,</span><br><span class="line">                use: fileLoader.concat(env===<span class="string">'production'</span></span><br><span class="line">                  ? [</span><br><span class="line">                    &#123;</span><br><span class="line">                      loader: <span class="string">'img-loader'</span>,</span><br><span class="line">                      options: &#123;</span><br><span class="line">                        pngquant: &#123;</span><br><span class="line">                          quality: <span class="number">80</span></span><br><span class="line">                        &#125;</span><br><span class="line">                      &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                  ]</span><br><span class="line">                  : []</span><br><span class="line">                )</span><br><span class="line">              &#125;,</span><br><span class="line">              &#123;</span><br><span class="line">                test: <span class="regexp">/\.(eot|woff2?|ttf|svg)$/</span>,</span><br><span class="line">                use: fileLoader</span><br><span class="line">              &#125;</span><br><span class="line">          ]</span><br><span class="line">      &#125;,</span><br><span class="line">      plugins: [</span><br><span class="line">        extractLess,</span><br><span class="line"></span><br><span class="line">        <span class="keyword">new</span> ProgressBarPlugin(&#123;</span><br><span class="line">          format: <span class="string">'  build [:bar] '</span> + chalk.green.bold(<span class="string">':percent'</span>) + <span class="string">' (:elapsed seconds)'</span>,</span><br><span class="line">          clear: <span class="literal">false</span></span><br><span class="line">        &#125;),</span><br><span class="line">        <span class="keyword">new</span> HtmlWebpackPlugin(&#123;</span><br><span class="line">    			inject: <span class="literal">true</span>,</span><br><span class="line">    			template: path.resolve(__dirname,<span class="string">'../public/index.html'</span>),</span><br><span class="line">          minify: &#123;</span><br><span class="line">            collapseWhitespace: <span class="literal">true</span></span><br><span class="line">          &#125;</span><br><span class="line">    		&#125;),</span><br><span class="line">        <span class="keyword">new</span> webpack.ProvidePlugin(&#123;</span><br><span class="line">          $: <span class="string">'jquery'</span></span><br><span class="line">        &#125;)</span><br><span class="line">      ]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = <span class="function"><span class="params">env</span> =&gt;</span>&#123;</span><br><span class="line">  <span class="keyword">const</span> config = env===<span class="string">'development'</span> ? developmentConfig : productionConfig</span><br><span class="line">  <span class="keyword">return</span> merge(generateConfig(env),config)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>开发环境配置 <code>build/webpack.dev.conf.js</code></p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> webpack = <span class="built_in">require</span>(<span class="string">'webpack'</span>)</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    devtool: <span class="string">'cheap-module-eval-source-map'</span>,<span class="comment">//开启sourcemap</span></span><br><span class="line">    devServer: &#123;</span><br><span class="line">        port: <span class="number">9001</span>,</span><br><span class="line">        <span class="comment">// 输入任意路径都不会出现404 都会重定向</span></span><br><span class="line">        historyApiFallback: <span class="literal">true</span>,</span><br><span class="line">        <span class="comment">// historyApiFallback: &#123;</span></span><br><span class="line">            <span class="comment">//从一个确定的url指向对应的文件</span></span><br><span class="line">            <span class="comment">//rewrites: [</span></span><br><span class="line">            <span class="comment">//    &#123;</span></span><br><span class="line">            <span class="comment">//        from: '/pages/a',// 可以写正则</span></span><br><span class="line">           <span class="comment">//         to: '/pages/a.html'</span></span><br><span class="line">            <span class="comment">//    &#125;</span></span><br><span class="line">            <span class="comment">// rewrites: [</span></span><br><span class="line">            <span class="comment">//     &#123;</span></span><br><span class="line">            <span class="comment">//         from: /^\/([a-zA-Z0-9]+\/?)([a-zA-Z0-9]+)/</span></span><br><span class="line">            <span class="comment">//         to: function(context)&#123;</span></span><br><span class="line">            <span class="comment">//             return '/' + context.match[1] + context.match[2] + '.html'</span></span><br><span class="line">            <span class="comment">//         &#125;</span></span><br><span class="line">            <span class="comment">//     &#125;</span></span><br><span class="line">            <span class="comment">// ]</span></span><br><span class="line">        <span class="comment">// &#125;,</span></span><br><span class="line">        hot:<span class="literal">true</span>,<span class="comment">//开启模块热更新</span></span><br><span class="line">        hotOnly:<span class="literal">true</span>,</span><br><span class="line">        overlay:<span class="literal">true</span>,<span class="comment">//错误提示</span></span><br><span class="line">        proxy: &#123;</span><br><span class="line">            <span class="string">'/api'</span>: &#123;</span><br><span class="line">                <span class="comment">// target: 'http://blog.poetries.top',//代理到服务器</span></span><br><span class="line">                changeOrigin:<span class="literal">true</span>,</span><br><span class="line">                logLevel: <span class="string">'debug'</span>,</span><br><span class="line">                <span class="comment">// pathRewite: &#123; &#125;,</span></span><br><span class="line">                headers:&#123;&#125;<span class="comment">// 请求头</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    plugins: [</span><br><span class="line">      <span class="comment">// 模块热更新插件</span></span><br><span class="line">       <span class="keyword">new</span> webpack.HotModuleReplacementPlugin(),</span><br><span class="line"></span><br><span class="line">       <span class="comment">// 输出热更新路径</span></span><br><span class="line">       <span class="keyword">new</span> webpack.NamedModulesPlugin()</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>生产环境配置 <code>build/webpack.prod.conf.js</code></p>
</blockquote>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> webpack = <span class="built_in">require</span>(<span class="string">'webpack'</span>)</span><br><span class="line"><span class="keyword">const</span> PurifyCssWebpack = <span class="built_in">require</span>(<span class="string">'purifycss-webpack'</span>)</span><br><span class="line"><span class="keyword">const</span> ExtractTextWebpackPlugin = <span class="built_in">require</span>(<span class="string">'extract-text-webpack-plugin'</span>)</span><br><span class="line"><span class="keyword">const</span> HtmlWebpackPlugin = <span class="built_in">require</span>(<span class="string">'html-webpack-plugin'</span>)</span><br><span class="line"><span class="keyword">const</span> CleanWebpackPlugin = <span class="built_in">require</span>(<span class="string">'clean-webpack-plugin'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"><span class="keyword">const</span> glob = <span class="built_in">require</span>(<span class="string">'glob-all'</span>)<span class="comment">//处理多个路径</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  plugins: [</span><br><span class="line">    <span class="keyword">new</span> PurifyCssWebpack(&#123;</span><br><span class="line">      paths: glob.sync([</span><br><span class="line">        <span class="string">'./*html'</span>,</span><br><span class="line">        <span class="string">'./src/*js'</span></span><br><span class="line">      ])</span><br><span class="line">    &#125;),</span><br><span class="line">    <span class="keyword">new</span> webpack.optimize.CommonsChunkPlugin(&#123;</span><br><span class="line">      name: <span class="string">'manifest'</span></span><br><span class="line">    &#125;),</span><br><span class="line">    <span class="keyword">new</span> HtmlWebpackPlugin(&#123;</span><br><span class="line">      inlineChunks: [<span class="string">'manifest'</span>]</span><br><span class="line">    &#125;),</span><br><span class="line">    <span class="keyword">new</span> webpack.optimize.UglifyJsPlugin(),</span><br><span class="line">    <span class="keyword">new</span> CleanWebpackPlugin([<span class="string">'../build'</span>])</span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="5-3-使用-middleware-来搭建开发环境"><a href="#5-3-使用-middleware-来搭建开发环境" class="headerlink" title="5.3 使用 middleware 来搭建开发环境"></a>5.3 使用 middleware 来搭建开发环境</h3><blockquote>
<p>可以更灵活配置,需要以下插件搭建</p>
</blockquote>
<ul>
<li><code>Express or koa</code></li>
<li><code>webpack-dev-middleware</code></li>
<li><code>webpack-hot-middleware</code> 热更新</li>
<li><code>http-proxy-middleware</code> 代理</li>
<li><code>connect-history-api-fallback</code> 地址rewrite</li>
<li><code>opn</code> 命令工具打开浏览器页面</li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// build/server.js</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 使用middleware搭建服务:更灵活配置,不在使用webpack-dev-server</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@type <span class="type">&#123;[type]&#125;</span></span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> express = <span class="built_in">require</span>(<span class="string">'express'</span>)</span><br><span class="line"><span class="keyword">const</span> webpack = <span class="built_in">require</span>(<span class="string">'webpack'</span>)</span><br><span class="line"><span class="keyword">const</span> opn = <span class="built_in">require</span>(<span class="string">'opn'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> app = express()</span><br><span class="line"><span class="keyword">const</span> port = <span class="number">3000</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//把express和配置联合起来 需要用到middleware</span></span><br><span class="line"><span class="keyword">const</span> webpackDevMiddleware = <span class="built_in">require</span>(<span class="string">'webpack-dev-middleware'</span>)</span><br><span class="line"><span class="keyword">const</span> webpackHotMiddleware = <span class="built_in">require</span>(<span class="string">'webpack-hot-middleware'</span>)</span><br><span class="line"><span class="keyword">const</span> proxyMiddleware = <span class="built_in">require</span>(<span class="string">'http-proxy-middleware'</span>)</span><br><span class="line"><span class="keyword">const</span> historyApiFallback = <span class="built_in">require</span>(<span class="string">'connect-history-api-fallback'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> config = <span class="built_in">require</span>(<span class="string">'./webpack.common.conf'</span>)(&#123;<span class="attr">env</span>:<span class="string">'development'</span>&#125;)</span><br><span class="line"><span class="keyword">const</span> compiler = webpack(config) <span class="comment">//给express使用</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> proxyTable = <span class="built_in">require</span>(<span class="string">'./proxy'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> context <span class="keyword">in</span> proxyTable)&#123;</span><br><span class="line">  app.use(proxyMiddleware(context, proxyTable[context]))</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">app.use(historyApiFallback(<span class="built_in">require</span>(<span class="string">'./historyfallback'</span>)))</span><br><span class="line"></span><br><span class="line">app.use(webpackDevMiddleware(compiler, &#123;</span><br><span class="line">  publicPath: config.output.publicPath</span><br><span class="line">&#125;))</span><br><span class="line"></span><br><span class="line">app.use(webpackHotMiddleware(compiler))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">app.listen(port, <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'&gt; Ready on:'</span> + port)</span><br><span class="line">  opn(<span class="string">'http://localhost:'</span> + port)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="六、webpack实战场景"><a href="#六、webpack实战场景" class="headerlink" title="六、webpack实战场景"></a>六、webpack实战场景</h2><h3 id="6-1-分析打包结果"><a href="#6-1-分析打包结果" class="headerlink" title="6.1 分析打包结果"></a>6.1 分析打包结果</h3><blockquote>
<p><a href="http://blog.poetries.top/2018/11/20/webpack-bundleAnalyzer/">http://blog.poetries.top/2018/11/20/webpack-bundleAnalyzer/</a></p>
</blockquote>
<h3 id="6-2-优化打包速度"><a href="#6-2-优化打包速度" class="headerlink" title="6.2 优化打包速度"></a>6.2 优化打包速度</h3><h4 id="6-2-1-方法一：分开vendor和app"><a href="#6-2-1-方法一：分开vendor和app" class="headerlink" title="6.2.1 方法一：分开vendor和app"></a>6.2.1 方法一：分开vendor和app</h4><blockquote>
<p>分开第三方代码和业务代码，借助<code>DllPlugin</code>和<code>DllReferencePlugin</code></p>
</blockquote>
<p><strong>之前的打包时间</strong></p>
<blockquote>
<p>现在我们来优化这个时间</p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/656.png" alt></p>
<p><strong>第一步：新建<code>webpack.dll.conf.js</code></strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// build/webpack.dll.conf.js</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"><span class="keyword">const</span> webpack = <span class="built_in">require</span>(<span class="string">'webpack'</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  entry: &#123;</span><br><span class="line">    <span class="comment">// 把这些资源打包成dll，提高编译速度</span></span><br><span class="line">    react: [<span class="string">'react'</span>,<span class="string">'react-router-dom'</span>,<span class="string">'redux'</span>,<span class="string">'redux-immutable'</span>,<span class="string">'immutable'</span>,<span class="string">'react-redux'</span>,<span class="string">'react-router'</span>,<span class="string">'redux-logger'</span>,<span class="string">'redux-thunk'</span>,<span class="string">'styled-components'</span>],</span><br><span class="line">    ui: [<span class="string">'antd-mobile'</span>,<span class="string">'antd'</span>],</span><br><span class="line">    others: [<span class="string">'react-icons'</span>,<span class="string">'axios'</span>,<span class="string">'clipboard'</span>,<span class="string">'humps'</span>,<span class="string">'lodash'</span>,<span class="string">'md5'</span>,<span class="string">'moment'</span>,<span class="string">'normalizr'</span>]</span><br><span class="line">  &#125;,</span><br><span class="line">  output: &#123;</span><br><span class="line">    path: path.resolve(__dirname, <span class="string">"../dll/"</span>),</span><br><span class="line">    filename: <span class="string">'[name].dll.js'</span>,</span><br><span class="line">    library: <span class="string">'[name]'</span></span><br><span class="line">  &#125;,</span><br><span class="line">  plugins: [</span><br><span class="line">    <span class="keyword">new</span> webpack.DllPlugin(&#123;</span><br><span class="line">      path: path.join(__dirname,<span class="string">'../dll/'</span>,<span class="string">'[name]-manifest.json'</span>),</span><br><span class="line">      name: <span class="string">'[name]'</span></span><br><span class="line">    &#125;),</span><br><span class="line">    <span class="keyword">new</span> webpack.optimize.UglifyJsPlugin()</span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>第二步：加一个命令</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// package.json</span></span><br><span class="line"><span class="string">"scripts"</span>: &#123;</span><br><span class="line">  <span class="string">"dll"</span>: <span class="string">"webpack --config config/webpack.dll.conf.js"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>执行<code>npm run dll</code></p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/657.png" alt></p>
<p><strong>第三步： 在plugins中增加配置</strong></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// build/webpack.prod.conf.js</span></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">   plugins: [</span><br><span class="line">        <span class="keyword">new</span> webpack.DllReferencePlugin(&#123;</span><br><span class="line">          manifest: <span class="built_in">require</span>(<span class="string">'../dll/react-manifest.json'</span>)</span><br><span class="line">        &#125;),</span><br><span class="line">        <span class="keyword">new</span> webpack.DllReferencePlugin(&#123;</span><br><span class="line">          manifest: <span class="built_in">require</span>(<span class="string">'../dll/ui-manifest.json'</span>)</span><br><span class="line">        &#125;),</span><br><span class="line">        <span class="keyword">new</span> webpack.DllReferencePlugin(&#123;</span><br><span class="line">          manifest: <span class="built_in">require</span>(<span class="string">'../dll/others-manifest.json'</span>)</span><br><span class="line">        &#125;)</span><br><span class="line">   ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>再次执行<code>npm run build</code></p>
</blockquote>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/658.png" alt></p>
<p>编译时间大大减少了</p>
<h4 id="6-2-2-方法二：UglifyJsPlugin并行处理"><a href="#6-2-2-方法二：UglifyJsPlugin并行处理" class="headerlink" title="6.2.2 方法二：UglifyJsPlugin并行处理"></a>6.2.2 方法二：UglifyJsPlugin并行处理</h4><p><strong>UglifyJsPlugin</strong></p>
<ul>
<li><code>parallel</code></li>
<li><code>cache</code></li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// build/webpack.prod.conf.js</span></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">   plugins: [</span><br><span class="line">        <span class="keyword">new</span> UglifyJsPlugin(&#123;</span><br><span class="line">          parallel:<span class="literal">true</span>, <span class="comment">//并行处理</span></span><br><span class="line">          cache: <span class="literal">true</span></span><br><span class="line">        &#125;)</span><br><span class="line">   ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="6-2-3-方法三：happyPack"><a href="#6-2-3-方法三：happyPack" class="headerlink" title="6.2.3 方法三：happyPack"></a>6.2.3 方法三：happyPack</h4><blockquote>
<p><code>happyPack</code>把所有串行的东西并行处理,使得<code>loader</code>并行处理，较少文件处理时间</p>
</blockquote>
<p><a href="https://www.npmjs.com/package/happypack" target="_blank" rel="noopener">https://www.npmjs.com/package/happypack</a></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">// build/webpack.prod.conf.js</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// @file: webpack.config.js</span></span><br><span class="line"><span class="keyword">const</span> HappyPack = <span class="built_in">require</span>(<span class="string">'happypack'</span>);</span><br><span class="line"> </span><br><span class="line">exports.module = &#123;</span><br><span class="line">  rules: [</span><br><span class="line">    &#123;</span><br><span class="line">      test: <span class="regexp">/.js$/</span>,</span><br><span class="line">      <span class="comment">// 1) replace your original list of loaders with "happypack/loader":</span></span><br><span class="line">      <span class="comment">// loaders: [ 'babel-loader?presets[]=es2015' ],</span></span><br><span class="line">      use: <span class="string">'happypack/loader'</span>,</span><br><span class="line">      include: [ <span class="comment">/* ... */</span> ],</span><br><span class="line">      exclude: [ <span class="comment">/* ... */</span> ]</span><br><span class="line">    &#125;</span><br><span class="line">  ],</span><br><span class="line">  plugins: [</span><br><span class="line">     <span class="comment">// 2) create the plugin:</span></span><br><span class="line">    <span class="keyword">new</span> HappyPack(&#123;</span><br><span class="line">        <span class="comment">// 3) re-add the loaders you replaced above in #1:</span></span><br><span class="line">        loaders: [ <span class="string">'babel-loader?presets[]=es2015'</span> ]</span><br><span class="line">    &#125;)</span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这时的编译时间也减小了一些</p>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/659.png" alt></p>
<h4 id="6-2-4-方法四：较少babel-loader编译时间"><a href="#6-2-4-方法四：较少babel-loader编译时间" class="headerlink" title="6.2.4 方法四：较少babel-loader编译时间"></a>6.2.4 方法四：较少babel-loader编译时间</h4><p><strong>babel-loader</strong></p>
<blockquote>
<p>开启缓存，指定编译范围</p>
</blockquote>
<ul>
<li><code>options.cache</code></li>
<li><code>include</code></li>
<li><code>exclude</code></li>
</ul>
<h4 id="6-2-5-其他"><a href="#6-2-5-其他" class="headerlink" title="6.2.5 其他"></a>6.2.5 其他</h4><ul>
<li>减少<code>resolve</code></li>
<li><code>Devtool</code>去除<code>sourcemap</code></li>
<li><code>cache-loader</code></li>
<li>升级<code>node</code></li>
<li>升级<code>webpack</code></li>
</ul>
<h3 id="6-3-长缓存优化"><a href="#6-3-长缓存优化" class="headerlink" title="6.3 长缓存优化"></a>6.3 长缓存优化</h3><p><strong>场景</strong></p>
<blockquote>
<p>改变<code>app</code>代码，<code>vendor</code>变化</p>
</blockquote>
<p><strong>解决</strong></p>
<ul>
<li>提取<code>vendor</code></li>
<li><code>hash</code>–&gt; <code>chunkhash</code>(把<code>hash</code>变为代码块的<code>hash</code>，而不是文件的<code>hash</code>)</li>
<li>提取<code>webpack runtime</code></li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">output: &#123;</span><br><span class="line">    path: path.resolve(__dirname, <span class="string">'../build/'</span>),</span><br><span class="line">    filename: <span class="string">'static/js/[name].[chunkhash:5].js'</span>,</span><br><span class="line">    chunkFilename: <span class="string">'static/js/[name].[chunkhash:8].chunk.js'</span>,</span><br><span class="line">    publicPath: <span class="string">'/'</span> <span class="comment">//浏览器中访问资源的路径</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><img src="https://poetries1.gitee.io/img-repo/2019/10/660.png" alt></p>
<blockquote>
<p>每次打包<code>vendor</code>都不会变化，这样就达到了缓存的目的（服务端开启<code>cache-ctrol</code>）</p>
</blockquote>
<p><strong>场景：引入新模块，模块顺序变化，vendor hash变化</strong></p>
<blockquote>
<p>解决： <code>NamedChunksPlugin</code> <code>NamedModulesPlugin</code></p>
</blockquote>
<p>对于动态模块引入需要给名称</p>
<h3 id="6-4-多页面应用"><a href="#6-4-多页面应用" class="headerlink" title="6.4 多页面应用"></a>6.4 多页面应用</h3><h4 id="6-4-1-多页面特点"><a href="#6-4-1-多页面特点" class="headerlink" title="6.4.1 多页面特点"></a>6.4.1 多页面特点</h4><ul>
<li>多入口</li>
<li>多页面<code>HTML</code></li>
<li>每个页面不同的<code>chunk</code></li>
<li>每个页面不同的参数</li>
</ul>
<h4 id="6-4-2-多页面多配置"><a href="#6-4-2-多页面多配置" class="headerlink" title="6.4.2 多页面多配置"></a>6.4.2 多页面多配置</h4><blockquote>
<p><code>wepback从3.1.0</code>开始支持</p>
</blockquote>
<p> <strong>优点</strong>：</p>
<ul>
<li>可以使用<code>parallel-webpack</code>(并行处理多份配置)提高打包速度<ul>
<li>配置更独立、灵活</li>
</ul>
</li>
</ul>
<p><strong>缺点</strong></p>
<ul>
<li>不能多页面之间共享代码</li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//package.json</span></span><br><span class="line"></span><br><span class="line">&#123;</span><br><span class="line">  <span class="string">"name"</span>: <span class="string">"多页面配置"</span>,</span><br><span class="line">  <span class="string">"version"</span>: <span class="string">"0.1.0"</span>,</span><br><span class="line">  <span class="string">"private"</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="string">"dependencies"</span>: &#123;</span><br><span class="line">    <span class="string">"clean-webpack-plugin"</span>: <span class="string">"^1.0.0"</span>,</span><br><span class="line">    <span class="string">"css-loader"</span>: <span class="string">"^1.0.1"</span>,</span><br><span class="line">    <span class="string">"ejs-loader"</span>: <span class="string">"^0.3.1"</span>,</span><br><span class="line">    <span class="string">"file-loader"</span>: <span class="string">"^2.0.0"</span>,</span><br><span class="line">    <span class="string">"html-loader"</span>: <span class="string">"^0.5.5"</span>,</span><br><span class="line">    <span class="string">"html-webpack-plugin"</span>: <span class="string">"^3.2.0"</span>,</span><br><span class="line">    <span class="string">"react"</span>: <span class="string">"^16.3.1"</span>,</span><br><span class="line">    <span class="string">"style-loader"</span>: <span class="string">"^0.23.1"</span>,</span><br><span class="line">    <span class="string">"webpack"</span>: <span class="string">"^4.26.0"</span>,</span><br><span class="line">    <span class="string">"webpack-merge"</span>: <span class="string">"^4.1.4"</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="string">"scripts"</span>: &#123;&#125;,</span><br><span class="line">  <span class="string">"devDependencies"</span>: &#123;</span><br><span class="line">    <span class="string">"extract-text-webpack-plugin"</span>: <span class="string">"^4.0.0-beta.0"</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 多页面多配置</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@type <span class="type">&#123;[type]&#125;</span></span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> merge = <span class="built_in">require</span>(<span class="string">'webpack-merge'</span>)</span><br><span class="line"><span class="keyword">const</span> webpack = <span class="built_in">require</span>(<span class="string">'webpack'</span>)</span><br><span class="line"><span class="keyword">const</span> HtmlWebpackPlugin = <span class="built_in">require</span>(<span class="string">'html-webpack-plugin'</span>)</span><br><span class="line"><span class="keyword">const</span> CleanWebpack = <span class="built_in">require</span>(<span class="string">'clean-webpack-plugin'</span>)</span><br><span class="line"><span class="keyword">const</span> ExtractTextwebpack = <span class="built_in">require</span>(<span class="string">'extract-text-webpack-plugin'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> baseConfig = &#123;</span><br><span class="line">    mode: <span class="string">'development'</span>,</span><br><span class="line">    entry: &#123;</span><br><span class="line">        react: <span class="string">'react'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">      rules: [</span><br><span class="line">        &#123;</span><br><span class="line">          test: <span class="regexp">/\.css$/</span>,</span><br><span class="line">          use: ExtractTextwebpack.extract(&#123;</span><br><span class="line">            fallback: <span class="string">'style-loader'</span>,</span><br><span class="line">            use: <span class="string">'css-loader'</span></span><br><span class="line">          &#125;)</span><br><span class="line">        &#125;</span><br><span class="line">      ]</span><br><span class="line">    &#125;,</span><br><span class="line">    output: &#123;</span><br><span class="line">        path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">        filename: <span class="string">'js/[name].[chunkhash].js'</span></span><br><span class="line">    &#125;,</span><br><span class="line">    plugins: [</span><br><span class="line">        <span class="keyword">new</span> ExtractTextwebpack(&#123;</span><br><span class="line">          filename: <span class="string">'css/[name].[hash].css'</span></span><br><span class="line">        &#125;),</span><br><span class="line">        <span class="keyword">new</span> CleanWebpack([<span class="string">'./dist'</span>])</span><br><span class="line">    ],</span><br><span class="line">    optimization: &#123;</span><br><span class="line">      splitChunks: &#123;</span><br><span class="line">          cacheGroups: &#123;</span><br><span class="line">              commons: &#123;</span><br><span class="line">                  <span class="comment">// commons里面的name就是生成的共享模块bundle的名字</span></span><br><span class="line">                  name: <span class="string">"react"</span>,</span><br><span class="line">                  <span class="comment">// chunks 有三个可选值，”initial”, “async” 和 “all”. 分别对应优化时只选择初始的chunks，所需要的chunks 还是所有chunks</span></span><br><span class="line">                  chunks: <span class="string">"initial"</span>,</span><br><span class="line">                  minChunks: <span class="literal">Infinity</span></span><br><span class="line">              &#125;</span><br><span class="line">          &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//生成每个页面配置</span></span><br><span class="line"><span class="keyword">const</span> generatePage = <span class="function"><span class="keyword">function</span>(<span class="params">&#123;</span></span></span><br><span class="line"><span class="function"><span class="params">    title = <span class="string">''</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">    entry = <span class="string">''</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">    template = <span class="string">'./src/index.html'</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">    name = <span class="string">''</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">    chunks = []</span></span></span><br><span class="line"><span class="function"><span class="params">&#125; = &#123;&#125;</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">        entry,</span><br><span class="line">        plugins: [</span><br><span class="line">            <span class="keyword">new</span> HtmlWebpackPlugin(&#123;</span><br><span class="line">                chunks,</span><br><span class="line">                template:<span class="string">`!!html-loader!<span class="subst">$&#123;template&#125;</span>`</span>,</span><br><span class="line">                filename: name + <span class="string">'.html'</span></span><br><span class="line">            &#125;)</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> pages = [</span><br><span class="line">  generatePage(&#123;</span><br><span class="line">      title: <span class="string">'page A'</span>,</span><br><span class="line">      entry: &#123;</span><br><span class="line">        a: <span class="string">'./src/pages/a'</span></span><br><span class="line">      &#125;,</span><br><span class="line">      name: <span class="string">'a'</span>,</span><br><span class="line">      chunks: [<span class="string">'react'</span>,<span class="string">'a'</span>]</span><br><span class="line">  &#125;),</span><br><span class="line">  generatePage(&#123;</span><br><span class="line">      title: <span class="string">'page B'</span>,</span><br><span class="line">      entry: &#123;</span><br><span class="line">        b: <span class="string">'./src/pages/b'</span></span><br><span class="line">      &#125;,</span><br><span class="line">      name: <span class="string">'b'</span>,</span><br><span class="line">      chunks: [<span class="string">'react'</span>,<span class="string">'b'</span>]</span><br><span class="line">  &#125;),</span><br><span class="line">  generatePage(&#123;</span><br><span class="line">      title: <span class="string">'page C'</span>,</span><br><span class="line">      entry: &#123;</span><br><span class="line">        c: <span class="string">'./src/pages/c'</span></span><br><span class="line">      &#125;,</span><br><span class="line">      name: <span class="string">'c'</span>,</span><br><span class="line">      chunks: [<span class="string">'react'</span>,<span class="string">'c'</span>]</span><br><span class="line">  &#125;)</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = pages.map(<span class="function"><span class="params">page</span>=&gt;</span>merge(baseConfig, page))</span><br></pre></td></tr></table></figure>
<h4 id="6-4-3-多页面单配置"><a href="#6-4-3-多页面单配置" class="headerlink" title="6.4.3 多页面单配置"></a>6.4.3 多页面单配置</h4><blockquote>
<p>多个页面共享一个配置</p>
</blockquote>
<ul>
<li>优点：可以共享各个<code>entry</code>之间公用代码</li>
<li>缺点：打包速度比较慢，输出的内容比较复杂</li>
</ul>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 多页面单配置</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> merge = <span class="built_in">require</span>(<span class="string">'webpack-merge'</span>)</span><br><span class="line"> <span class="keyword">const</span> webpack = <span class="built_in">require</span>(<span class="string">'webpack'</span>)</span><br><span class="line"> <span class="keyword">const</span> HtmlWbpackPlugin = <span class="built_in">require</span>(<span class="string">'html-webpack-plugin'</span>)</span><br><span class="line"> <span class="keyword">const</span> CleanWebpack = <span class="built_in">require</span>(<span class="string">'clean-webpack-plugin'</span>)</span><br><span class="line"> <span class="keyword">const</span> ExtractTextwebpack = <span class="built_in">require</span>(<span class="string">"extract-text-webpack-plugin"</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> baseConfig = &#123;</span><br><span class="line">     mode: <span class="string">'development'</span>,</span><br><span class="line">     entry: &#123;</span><br><span class="line">         react: <span class="string">'react'</span></span><br><span class="line">     &#125;,</span><br><span class="line">     <span class="built_in">module</span>: &#123;</span><br><span class="line">       rules: [</span><br><span class="line">         &#123;</span><br><span class="line">           test: <span class="regexp">/\.css$/</span>,</span><br><span class="line">           use: ExtractTextwebpack.extract(&#123;</span><br><span class="line">             fallback: <span class="string">'style-loader'</span>,</span><br><span class="line">             use: <span class="string">'css-loader'</span></span><br><span class="line">           &#125;)</span><br><span class="line">         &#125;</span><br><span class="line">       ]</span><br><span class="line">     &#125;,</span><br><span class="line">     output: &#123;</span><br><span class="line">         path: path.resolve(__dirname, <span class="string">'dist'</span>),</span><br><span class="line">         filename: <span class="string">'js/[name].[chunkhash].js'</span></span><br><span class="line">     &#125;,</span><br><span class="line">     plugins: [</span><br><span class="line">         <span class="keyword">new</span> ExtractTextwebpack(&#123;</span><br><span class="line">           filename: <span class="string">'css/[name].[hash].css'</span></span><br><span class="line">         &#125;),</span><br><span class="line">         <span class="keyword">new</span> CleanWebpack(path.resolve(__dirname, <span class="string">'dist'</span>))</span><br><span class="line">     ],</span><br><span class="line">     optimization: &#123;</span><br><span class="line">       splitChunks: &#123;</span><br><span class="line">           cacheGroups: &#123;</span><br><span class="line">               commons: &#123;</span><br><span class="line">                   <span class="comment">// commons里面的name就是生成的共享模块bundle的名字</span></span><br><span class="line">                   name: <span class="string">"react"</span>,</span><br><span class="line">                   <span class="comment">// chunks 有三个可选值，”initial”, “async” 和 “all”. 分别对应优化时只选择初始的chunks，所需要的chunks 还是所有chunks</span></span><br><span class="line">                   chunks: <span class="string">"initial"</span>,</span><br><span class="line">                   minChunks: <span class="literal">Infinity</span></span><br><span class="line">               &#125;</span><br><span class="line">           &#125;</span><br><span class="line">       &#125;</span><br><span class="line">     &#125;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">//生成每个页面配置</span></span><br><span class="line"> <span class="keyword">const</span> generatePage = <span class="function"><span class="keyword">function</span>(<span class="params">&#123;</span></span></span><br><span class="line"><span class="function"><span class="params">     title = <span class="string">''</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">     entry = <span class="string">''</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">     template = <span class="string">'./src/index.html'</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">     name = <span class="string">''</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">     chunks = []</span></span></span><br><span class="line"><span class="function"><span class="params"> &#125; = &#123;&#125;</span>)</span>&#123;</span><br><span class="line">     <span class="keyword">return</span> &#123;</span><br><span class="line">         entry,</span><br><span class="line">         plugins: [</span><br><span class="line">             <span class="keyword">new</span> HtmlWbpackPlugin(&#123;</span><br><span class="line">                 chunks,</span><br><span class="line">                 template:<span class="string">`!!html-loader!<span class="subst">$&#123;template&#125;</span>`</span>,</span><br><span class="line">                 title,</span><br><span class="line">                 filename: name + <span class="string">'.html'</span></span><br><span class="line">             &#125;)</span><br><span class="line">         ]</span><br><span class="line">     &#125;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> pages = [</span><br><span class="line">   generatePage(&#123;</span><br><span class="line">       title: <span class="string">'page A'</span>,</span><br><span class="line">       entry: &#123;</span><br><span class="line">         a: <span class="string">'./src/pages/a'</span></span><br><span class="line">       &#125;,</span><br><span class="line">       name: <span class="string">'a'</span>,</span><br><span class="line">       chunks: [<span class="string">'react'</span>,<span class="string">'a'</span>]</span><br><span class="line">   &#125;),</span><br><span class="line">   generatePage(&#123;</span><br><span class="line">       title: <span class="string">'page B'</span>,</span><br><span class="line">       entry: &#123;</span><br><span class="line">         b: <span class="string">'./src/pages/b'</span></span><br><span class="line">       &#125;,</span><br><span class="line">       name: <span class="string">'b'</span>,</span><br><span class="line">       chunks: [<span class="string">'react'</span>,<span class="string">'b'</span>]</span><br><span class="line">   &#125;),</span><br><span class="line">   generatePage(&#123;</span><br><span class="line">       title: <span class="string">'page C'</span>,</span><br><span class="line">       entry: &#123;</span><br><span class="line">         c: <span class="string">'./src/pages/c'</span></span><br><span class="line">       &#125;,</span><br><span class="line">       name: <span class="string">'c'</span>,</span><br><span class="line">       chunks: [<span class="string">'react'</span>,<span class="string">'c'</span>]</span><br><span class="line">   &#125;)</span><br><span class="line"> ]</span><br><span class="line"></span><br><span class="line"> <span class="built_in">module</span>.exports = merge([baseConfig].concat(pages))</span><br></pre></td></tr></table></figure>
<blockquote>
<p>完整例子 <a href="https://github.com/poetries/webpack-config-demo" target="_blank" rel="noopener">https://github.com/poetries/webpack-config-demo</a></p>
</blockquote>
<h2 id="七、更多学习"><a href="#七、更多学习" class="headerlink" title="七、更多学习"></a>七、更多学习</h2><ul>
<li><a href="https://juejin.im/post/5bb089e86fb9a05cd84935d0" target="_blank" rel="noopener">webpack4.0 入门篇 - 构建前端开发的基本环境</a></li>
<li><a href="https://juejin.im/post/5be45723e51d45305c2ceaf0?utm_source=gold_browser_extension#heading-2" target="_blank" rel="noopener">用于前端开发的webpack4配置[带注释]</a></li>
</ul>

      </div>
    
  </div>

</article>

<button class="assist-btn2 circle" id="assist_btn2" title="点亮屏幕" style="left: 27px; top: 152px;">
  <i class="iconfont" style="display:inline-block;color:red;width:20px;height:20px;">&#xe61d;</i>
</button>
<button class="assist-btn1 circle" id="assist_btn1" title="关闭屏幕亮度" style="left: 27px; top: 152px;">
  <i class="iconfont toc-title" style="display:inline-block;color:red;width:20px;height:20px;">&#xe61d;</i>
</button>


<script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>	

<script src="https://my.openwrite.cn/js/readmore.js" type="text/javascript"></script>
<script>
  const btw = new BTWPlugin();
  btw.init({
    id: "container",
    blogId: "22699-1592137983091-414",
    name: "前端进阶之旅",
    qrcode: "https://poetries1.gitee.io/img-repo/2020/06/qrcode.jpg",
    keyword: "3a3b3c",
  });
</script>

<script type="text/javascript">

// white theme
var body = {color: "#555", background: "#000"};
var a_tag = {color: "#222"};
var header = { background: "#222"};
var logo_line_i = {background: "#222"};
// var post_code = {background: "#eee", color: "#222"};

function switch_theme() {
 $("body").css(body);
 $("a:not('.links-of-author-item a, .site-state-item a, .site-state-posts a, .feed-link a, .motion-element a, .post-tags a, .show-commit-cls a, #donate_board a')").css(a_tag);
 $(".header, .footer").css(header);
 $(".logo-line-before i, .logo-line-after i").css(logo_line_i);
 //$(".post code").css(post_code);
 $("#idhyt-surprise-ball #idhyt-surprise-ball-animation .drag").css(a_tag);
 $(".post-title-link, .posts-expand .post-meta, .post-comments-count, .disqus-comment-count, .post-category a, .post-nav-next a, .post-nav-item a").css(a_tag);
 
 // $("code").css({color: '#c5c8c6', background: '#1d1f21'});
 //$("#assist_btn1").hide(1500);
}

$(function () {
$("#assist_btn2").css("display","none");
 $("#assist_btn1").click(function() {
     switch_theme();
$("div#toc.toc-article").css({
 "background":"#eaeaea",
 "opacity":1
});
$(".toc-article ol").show();
$("#toc.toc-article .toc-title").css("color","#a98602");
$("#assist_btn1").css("display","none");
$("#assist_btn2").css("display","block");
 });
$("#assist_btn2").click(function() {
$("#assist_btn2").css("display","none");
$("#assist_btn1").css("display","block");
$("body").css("background","url(http://www.miaov.com/static/ie/images/news/bg.png)")
     $(".header, .footer").css("background","url(http://www.miaov.com/static/ie/images/news/bg.png)")
$(".toc-article ol").toggle(1000);
 });
});


//背景随机

var Y, O, E, L, B, C, T, z, N, S, A, I;
!function() {
var e = function() {
for (O.clearRect(0, 0, L, B), T = [{
x: 0,
y: .7 * B + C
}, {
x: 0,
y: .7 * B - C
}]; T[1].x < L + C;) t(T[0], T[1])
}, t = function(e, t) {
O.beginPath(), O.moveTo(e.x, e.y), O.lineTo(t.x, t.y);
var n = t.x + (2 * I() - .25) * C,
 r = a(t.y);
O.lineTo(n, r), O.closePath(), N -= S / -50, O.fillStyle = "#" + (127 * A(N) + 128 << 16 | 127 * A(N + S / 3) + 128 << 8 | 127 * A(N + S / 3 * 2) + 128).toString(16), O.fill(), T[0] = T[1], T[1] = {
 x: n,
 y: r
}
}, a = function n(e) {
var t = e + (2 * I() - 1.1) * C;
return t > B || t < 0 ? n(e) : t
};
Y = document.getElementById("evanyou"), O = Y.getContext("2d"), E = window.devicePixelRatio || 1, L = window.innerWidth, B = window.innerHeight, C = 90, z = Math, N = 0, S = 2 * z.PI, A = z.cos, I = z.random, Y.width = L * E, Y.height = B * E, O.scale(E, E), O.globalAlpha = .6, document.onclick = e, document.ontouchstart = e, e()
}()

   
$("#toc-eye").click(function(){
$("#toc.toc-article").toggle(1000);
});

</script>


   
  <div class="text-center donation">
    <div class="inner-donation">
      <span class="btn-donation">支持一下</span>
      <div class="donation-body">
        <div class="tip text-center">扫一扫，支持poetries</div>
        <ul>
        
          <li class="item">
            
              <span>微信扫一扫</span>
            
            <img src="/images/weixin.jpg" alt="">
          </li>
        
          <li class="item">
            
              <span>支付宝扫一扫</span>
            
            <img src="/images/zhifubao.jpg" alt="">
          </li>
        
        </ul>
      </div>
    </div>
  </div>


   
  <div class="box-prev-next clearfix">
    <a class="show pull-left" href="/2018/11/20/webpack-config-optize/">
        <i class="icon icon-angle-left"></i>
    </a>
    <a class="show pull-right" href="/2018/11/23/eslint-conf-info/">
        <i class="icon icon-angle-right"></i>
    </a>
  </div>




</div>


  <a id="backTop" class="back-top">
    <i class="icon-angle-up"></i>
  </a>




  <div class="modal" id="modal">
  <span id="cover" class="cover hide"></span>
  <div id="modal-dialog" class="modal-dialog hide-dialog">
    <div class="modal-header">
      <span id="close" class="btn-close">关闭</span>
    </div>
    <hr>
    <div class="modal-body">
      <ul class="list-toolbox">
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/archives/"
              rel="noopener noreferrer"
              target="_self"
              >
              博客
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/categories/"
              rel="noopener noreferrer"
              target="_self"
              >
              分类
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/tags/"
              rel="noopener noreferrer"
              target="_self"
              >
              标签
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/search/"
              rel="noopener noreferrer"
              target="_self"
              >
              搜索
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/link/"
              rel="noopener noreferrer"
              target="_self"
              >
              友链
            </a>
          </li>
        
          <li class="item-toolbox">
            <a
              class="CIRCLE"
              href="/about/"
              rel="noopener noreferrer"
              target="_self"
              >
              关于
            </a>
          </li>
        
      </ul>

    </div>
  </div>
</div>



  
      <div class="fexo-comments comments-post">
    

    

    
    

    

    
    

    

<!-- Gitalk评论插件通用代码 -->
<div id="gitalk-container"></div>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.css">
<script src="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js"></script>
<script>
const gitalk = new Gitalk({
  clientID: '5567a2c4abb858009d96',
  clientSecret: 'b9039ec056cf5c2346b3cdb63308a28c163f91e5',
  repo: 'poetries.github.io',
  owner: 'poetries',
  // 在这里设置一下截取前50个字符串, 这是因为 github 对 label 的长度有了要求, 如果超过
  // 50个字符串则会报错.
  // id: location.pathname.split('/').pop().substring(0, 49),
  id: location.pathname,
  admin: ['poetries'],
  // facebook-like distraction free mode
  distractionFreeMode: false
})
gitalk.render('gitalk-container')
</script>
<!-- Gitalk代码结束 -->



  </div>

  

  <script type="text/javascript">
  function loadScript(url, callback) {
    var script = document.createElement('script')
    script.type = 'text/javascript';

    if (script.readyState) { //IE
      script.onreadystatechange = function() {
        if (script.readyState == 'loaded' ||
          script.readyState == 'complete') {
          script.onreadystatechange = null;
          callback();
        }
      };
    } else { //Others
      script.onload = function() {
        callback();
      };
    }

    script.src = url;
    document.getElementsByTagName('head')[0].appendChild(script);
  }

  window.onload = function() {
    loadScript('/js/bundle.js?235683', function() {
      // load success
    });
  }
</script>


  <!-- 页面点击小红心 -->
  <script type="text/javascript" src="/js/clicklove.js"></script>
 
  
</body>
</html>
